Cod sursa(job #997760)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 14 septembrie 2013 20:15:48
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.41 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <queue>
#include <bitset>
#include <cstring>

FILE *f=fopen("ubuntzei.in","r");
FILE *g=fopen("ubuntzei.out","w");

using namespace std;

const int INF = 0x3f3f3f3f;
const int Nmax = 2005,Mmax=10005,Kmax=17;

int N,M,K,v[Kmax+10];
int C[(1<<Kmax)+10][Kmax],cost[Kmax+10][Kmax+10];
int D[Kmax][Nmax];
bitset<Nmax>used[Kmax+10];
vector<int>G[Kmax+10];
vector<pair<int,int> > lv[Nmax];

void get_graph()
{
    fscanf(f,"%d%d%d",&N,&M,&K);
    v[1]=1;v[++K+1]=N;
    for(int i=2;i<=K;++i)fscanf(f,"%d",&v[i]);
    ++K;
    sort(v+1,v+K+1);
    int a,b,c;
    for(int i=1;i<=M;++i)
    {
        fscanf(f,"%d%d%d",&a,&b,&c);
        lv[a].push_back(make_pair(b,c));
        lv[b].push_back(make_pair(a,c));
    }
}

void bellman_ford(int nodc,int lvl)
{
    queue<int> Q;
    vector<pair<int,int> > ::iterator it;
    D[lvl][nodc]=0;
    Q.push(nodc);
    while(!Q.empty()){
        nodc=Q.front();
        Q.pop();
        used[lvl][nodc]=false;
        for(it=lv[nodc].begin();it!=lv[nodc].end();++it)
            if(D[lvl][it->first] > D[lvl][nodc] + it->second){
                D[lvl][it->first] = D[lvl][nodc] + it->second;
                if(!used[lvl][it->first]){
                        Q.push(it->first);
                        used[lvl][it->first]=true;
                    }
            }
    }
}
void make_newgraph()// aici creeam noul graf ( complet ) in care
{                   //trebuie sa determinam LANTUL hamiltonian de cost minim
    memset(cost,INF,sizeof(cost));
    for(int i=0;i<K;++i)
        for(int j=i+1;j<K;++j)
            if(i!=j){
                G[j].push_back(i);
                G[i].push_back(j);
                cost[i][j]=cost[j][i]=D[i+1][v[j+1]];
            }
}

void solve()
{
    memset(C,INF,sizeof(C));
    int i,j;
    vector<int> :: iterator it;
    C[1][0]=0;
    for(i = 1; i < (1 << K) ; ++i)
        for(j = 0; j < K; ++j)
            if( i & (1<<j) )
                for(it=G[j].begin(); it !=G[j].end();++it)
                    if(i & (1<<(*it)))
                        C[i][j]=min(C[i][j], C[i ^ (1<<j)][*it] + cost[*it][j]);
    int answer=C[(1<<K)-1][K-1];
    fprintf(g,"%d",answer);
}

int main()
{
    get_graph();
    memset(D,INF,sizeof(D));
    for(int i=1;i<=K;++i)
        bellman_ford(v[i],i);
    make_newgraph();
    solve();
    return 0;
}