Cod sursa(job #1517767)

Utilizator elevenstrArina Raileanu elevenstr Data 4 noiembrie 2015 20:06:58
Problema Ubuntzei Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.3 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[65535][35];
queue <int> Q;
vector <pair<int,  int> > v[MAX1];
vector < int> sp[MAX1];
 int n,k;
int c[20],e[MAX1],dist[MAX1],drum[MAX1][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;
                        }


                        sp[y].push_back(ind);
                        drum[y][ind]=dist[act]+it->second;
                        sp[ind].push_back(y);
                        drum[ind][y]=dist[act]+it->second;

                }
                dist[it->first]=dist[act]+it->second;
                Q.push(it->first);
            }
        }
    }
}
int main()
{
    int i,j,m,l,x,a,b,d,mini=INF;
    in>>n>>m>>k;
    for(i=1; i<=k; i++)
    {
        in>>c[i];
        e[c[i]]=1;
    }
    for(i=1; i<=m; i++)
    {
        in>>a>>b>>d;
        v[a].push_back(mp(b,d));
        v[b].push_back(mp(a,d));
    }
    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 (vector< int > ::iterator it=sp[j].begin();it!=sp[j].end();it++)
                    if (i & (1<<*it))
                        dp[i][j] = min(dp[i][j], dp[i ^ (1<<j)][ *it ] + drum[*it ][j]);

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

  out<<mini;

    return 0;
}