Cod sursa(job #2065947)

Utilizator RaduToporanRadu Toporan RaduToporan Data 14 noiembrie 2017 15:44:03
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.2 kb
#include <cstdio>
#include <vector>
#include <queue>
#define inf 2000000000
#define NSTARI (1<<17)+5

using namespace std;
int n,m,k,i,j,u[20],dist[20][20],x,y,c,dmin[2005],dp[NSTARI][20];
struct element
{
    int y,cost;
} e1,e2;
vector <element> v[2005];

class comp{
    public: bool operator()(int  &x, int &y){
            return dmin[x]>dmin[y];
    };
};

priority_queue <int,vector<int>, comp> q;

element make_elem(int y, int c)
{
    element elem;
    elem.y=y;
    elem.cost=c;
    return elem;
}

void dijkstra(int s)
{
    int nod,nod1,i;
    bool inheap[2005];
    for (i=1; i<=n; i++)
    {
        dmin[i]=inf;
        inheap[i]=0;
    }
    dmin[s]=0;
    q.push(s);
    inheap[s]=1;
    while (!q.empty())
    {
        nod=q.top();
        q.pop();
        inheap[nod]=0;
        for (int i=0; i<v[nod].size(); i++)
        {
            nod1=v[nod][i].y;
            if (dmin[nod1]>dmin[nod]+v[nod][i].cost)
            {
                dmin[nod1]=dmin[nod]+v[nod][i].cost;
                if (inheap[nod1]==0)
                {
                    q.push(nod1);
                    inheap[nod1]=1;
                }
            }
        }
    }
}

int main()
{
    freopen("ubuntzei.in","r",stdin);
    freopen("ubuntzei.out","w",stdout);
    scanf("%d%d%d",&n,&m,&k);
    u[1]=1;
    for (i=2; i<=k+1; i++)
        scanf("%d",&u[i]);
    k=k+2;
    u[k]=n;
    for (i=1; i<=m; i++)
    {
        scanf("%d%d%d",&x,&y,&c);
        e1=make_elem(y,c);
        e2=make_elem(x,c);
        v[x].push_back(e1);
        v[y].push_back(e2);
    }
    for (i=1; i<=k; i++)
    {
        dijkstra(u[i]);
        for (j=1; j<=k; j++)
            dist[i][j]=dmin[u[j]];
    }
    int nst=1<<k;
    for (i=1; i<nst; i++)
        for (j=1; j<=k; j++)
        dp[i][j]=inf;

    dp[1][1]=0;
    for (i=1; i<nst; i++)
    {
        for (int bit=1; bit<=k; bit++)
            if (i&&(1<<(bit-1))!=0)
            for(int bit1 = 1; bit1 <= k; bit1++)
                    if((i & (1<<(bit1-1)))!=0 && bit1 != bit)
dp[i][bit] = min(dp[i][bit], dp[i ^ (1<<(bit-1))][bit1] + dist[bit1][bit]);
    }
    printf("%d\n",dp[nst-1][k]);
    return 0;
}