Cod sursa(job #2684043)

Utilizator DeniszPop Denis Denisz Data 12 decembrie 2020 16:16:46
Problema Gather Scor 100
Compilator cpp-64 Status done
Runda dij Marime 2.84 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

#define inf 4294967295
#define min(a,b) (a < b ? a : b)

int n,m,K,l;
vector <unsigned int> a[751];
vector <unsigned int> b[751],cap[751];
int p[751],h[751],g[751];
unsigned int cost[751];
int unde[16];
unsigned int A[16][16][16];
unsigned int c[16][32768];
unsigned int sol;

inline unsigned int solve(int nod,int x,int nr)
{
    if (c[nod][x]==inf)
    {
        int i;
        unsigned int aux;
        nr--;
        for (i=0; i<K; i++)
            if (x&(1<<i) && i!=nod)
            {
                aux=solve(i,x-(1<<nod),nr);
                if (aux + 1LL * (nr+1) * A[i][nod][nr] < c[nod][x]) c[nod][x]=aux + (nr+1) * A[i][nod][nr];
            }
    }

    return c[nod][x];
}

inline void pop(int x)
{
    int aux;

    while (x/2>1 && cost[h[x]]<cost[h[x/2]])
    {
        aux=h[x];
        h[x]=h[x/2];
        h[x/2]=aux;

        p[h[x]]=x;
        p[h[x/2]]=x/2;

        x/=2;
    }
}

inline void push(int x)
{
    int aux,y=0;

    while (x!=y)
    {
        y=x;

        if (y*2<=l && cost[h[x]]>cost[h[y*2]]) x=y*2;
        if (y*2+1<=l && cost[h[x]]>cost[h[y*2+1]]) x=y*2+1;

        aux=h[x];
        h[x]=h[y];
        h[y]=aux;

        p[h[x]]=x;
        p[h[y]]=y;
    }
}

void Dijkstra(int nod,int capinf)
{
    int i;

    for (i=1; i<=n; i++)
    {
        cost[i]=inf;
        h[i]=i;
        p[i]=i;
    }

    l=n;
    cost[unde[nod]]=0;
    h[1]=unde[nod];
    h[unde[nod]]=1;
    p[1]=unde[nod];
    p[unde[nod]]=1;

    while (l>0)
    {
        for (i=0; i<g[h[1]]; i++)
            if (cap[h[1]][i]>=capinf && 0LL+cost[h[1]] + b[h[1]][i]<cost[a[h[1]][i]])
            {
                cost[a[h[1]][i]] = cost[h[1]] + b[h[1]][i];
                pop(p[a[h[1]][i]]);
            }

        p[h[1]]=0;
        h[1]=h[l];
        p[h[1]]=1;
        h[l]=0;
        l--;

        if (l>1) push(1);
    }

    for (i=0; i<K; i++) A[nod][i][capinf]=cost[unde[i]];
}

int main()
{
    ifstream fin("gather.in");
    ofstream fout("gather.out");

    int x,y,i,j;
    unsigned int z,t;
    fin>>K>>n>>m;

    for (i=0; i<K; i++) fin>>unde[i];
    unde[K]=1;

    for (i=1; i<=m; i++)
    {
        fin>>x>>y>>z>>t;
        a[x].push_back(y), b[x].push_back(z), cap[x].push_back(t);
        a[y].push_back(x), b[y].push_back(z), cap[y].push_back(t);
    }

    for (i=1; i<=n; i++) g[i]=a[i].size();

    for (i=0; i<=K; i++)
        for (j=0; j<=K; j++) Dijkstra(j,i);

    for (i=0; i<K; i++)
        for (j=0; j<1<<K; j++) c[i][j]=inf;

    for (i=0; i<K; i++) c[i][1<<i]=A[K][i][0];

    sol=inf;

    for (i=0; i<K; i++)
    {
        unsigned int aux=solve(i,(1<<K)-1,K);
        if (aux<sol) sol=aux;
    }

    fout<<sol;

    return 0;
}