Cod sursa(job #1110039)

Utilizator cat_red20Vasile Ioana cat_red20 Data 17 februarie 2014 19:53:40
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.22 kb
#include<fstream>
#include<queue>
#include<vector>
#define MAXN 2001
#define MAXM 10001
#define MAXS 1<<16
#define INF 1<<30
using namespace std;
int m,n,k,c[16],dist[18][MAXN],d[MAXS+1][16],viz[MAXN];
queue<int> q;
vector<pair<int,int> >v[MAXN];
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");

void citire()
{
    int x,y,z;
    fin>>n>>m;
    fin>>k;
    for(int i=0;i<k;i++)
        fin>>c[i];
    for(int i=1;i<=m;i++)
    {
        fin>>x>>y>>z;
        v[x].push_back(make_pair(y,z));
        v[y].push_back(make_pair(x,z));
    }
}

void init()
{
    for(int i=0;i<=k;i++)
    {
        for(int j=1;j<=n;j++)
            dist[i][j]=INF;
    }
}

void drum(int t)
{
    int nod,next,cost;
    q.push(c[t]);
    viz[c[t]]=1;
    dist[t][c[t]]=0;
    while(!q.empty())
    {
        nod=q.front();
        q.pop();
        viz[nod]=0;
        for(int i=0;i<v[nod].size();i++)
        {
            next=v[nod][i].first;
            cost=v[nod][i].second;
            if(dist[t][next]>dist[t][nod]+cost)
            {
                if(viz[next]==0)
                {
                    q.push(next);
                    viz[next]=1;
                }
                dist[t][next]=dist[t][nod]+cost;
            }
        }
    }
}

void pd()
{

    for(int i=1;i<=((1<<k)-1);i++)
        for(int j=0;j<k;j++)
            d[i][j]=INF;


    for(int i=0;i<k;i++)
    {
        d[1<<i][i]=dist[k][c[i]];
    }

    for(int i=1;i<=((1<<k)-1);i++)
    {
        for(int j=0;j<k;j++)
        {
            if((i&(1<<j))==0 || (i==(1<<j)))
                continue;
            for(int t=0;t<=k;t++)
            {
                if(t==j || (i&(1<<t))==0)
                    continue;
                d[i][j]=min(d[i][j],d[i^(1<<j)][t]+dist[t][c[j]]);
            }
        }
    }
}


void afisare()
{
    int sol=INF;
    for(int i=0;i<k;i++)
    {
        sol=min(sol,d[(1<<k)-1][i]+dist[i][n]);
    }
    if(k==0)
    {
        fout<<dist[k][n];
        return;
    }
    fout<<sol;
}

int main()
{
    citire();
    init();
    c[k]=1;
    for(int i=0;i<=k;i++)
    {
        drum(i);
    }
    pd();
    afisare();
    return 0;
}