Cod sursa(job #1518846)

Utilizator elevenstrArina Raileanu elevenstr Data 6 noiembrie 2015 15:19:05
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.17 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
#define mp(a,b) make_pair(a,b)
ifstream in("ubuntzei.in");
ofstream out("ubuntzei.out");

#define MAX1 10070
#define INF 12000000
 int dp[262144][35];
queue <int> Q;
vector <pair<int,  int> > v[MAX1];
 int n,k;
 int i,j,m,l,x,a,b,d,mini=INF;
int c[20],e[MAX1],dist[MAX1],drum[MAX1][MAX1];
vector<int> sp[MAX1];
inline void bell(int nod,long long int y)
{
    for(int i=0; i<=MAX1; i++)
        dist[i]=INF;
         dist[nod]=0;
    Q.push(nod);
    while(!Q.empty())
    {
        int act=Q.front();
        Q.pop();
        for(vector <pair<int,int> > ::iterator it=v[act].begin(); it!=v[act].end(); it++)
        {
            if(dist[it->first]>dist[act]+it->second)
            {
                if(e[it->first])
                {
                    int ind;
                    for(int i=1; i<=k; i++)
                        if(c[i]==it->first)
                        {
                            ind=i;
                            break;
                        }
                        drum[y][ind]=dist[act]+it->second;
                        drum[ind][y]=dist[act]+it->second;
                }
                dist[it->first]=dist[act]+it->second;
                Q.push(it->first);
            }
        }
    }
}
int main()
{

    in>>n>>m>>k;
    for(i=1; i<=k; i++)
    {
        in>>c[i];
        e[c[i]]=i;
    }
    for(i=1; i<=m; i++)
    {
        in>>a>>b>>d;
        v[a].push_back(mp(b,d));
        v[b].push_back(mp(a,d));
    }
    c[0]=1;
    c[k+1]=n;
    bell(1,0);
    if(k==0){out<<dist[n]; return 0;}
    for(i=1;i<=k;i++)
    bell(c[i],i);
    bell(n,k+1);
    for ( int i = 0; i < 1 << (k+2); ++i)
        for (int j = 0; j < k+2; ++j) dp[i][j] = INF;
    dp[1][0] = 0;
    for ( int i = 0; i < 1 << (k+2); ++i)
        for ( int j = 0; j < k+2; ++j)
            if (i & (1<<j))
                for (int l=0;l<k+2;l++)
                    if (i & (1<<l))
                        dp[i][j] = min(dp[i][j], dp[i^(1<<j)][l] + drum[l ][j]);

    mini = dp[(1<<(k+2))-1][k+1];

  out<<mini;

    return 0;
}