Cod sursa(job #1330603)

Utilizator bogdanmarin69Bogdan Marin bogdanmarin69 Data 30 ianuarie 2015 20:08:58
Problema Ubuntzei Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.83 kb
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
#define MAX 10003
#define INF 2000000000
#define DOI16 65536
ifstream fin("ubuntzei.in");
ofstream fout("ubuntzei.out");
vector <pair<int, int> > gf[MAX];
queue <int> q;
int n, m, k, vk[20], mat[20][20], d[MAX], dp[DOI16][16];
void bellman(int s);
void afis();
int hamilton();
int main()
{
    int i, j, u, v, w;
    fin>>n>>m>>k;
    vk[0] = 1; vk[k+1] = n;
    for(i=1; i<=k; i++) fin>>vk[i];
    for(i=1; i<=m; i++){
        fin>>u>>v>>w;
        gf[u].push_back(make_pair(v, w));
        gf[v].push_back(make_pair(u, w));
    }
    for(i=0; i<=k; i++){
        bellman(vk[i]);
        for(j=i+1; j<=k+1; j++)
            mat[i][j] = mat[j][i] = d[vk[j]];
    }
    fout<<hamilton();
    return 0;
}
int hamilton(){
    int i, j, rez=INF, p;

    for(i=0; i<DOI16; i++)
        for(j=0; j<=k; j++)
            dp[i][j] = INF;
    dp[1][0] = 0;
    for(i=0; i<(1<<(k+1)); i++)
        for(j=1; j<=k; j++)
            if(i & (1<<j))
                for(p=0; p<=k; p++)
                    if(i & (1<<p))
                        dp[i][j] = min(dp[i][j], dp[i ^ (1<<j)][p] + mat[p][j]);
    for(i=1; i<=k; i++)
        rez = min(rez, dp[(1<<(k+1))-1][i]+mat[i][k+1]);
    return rez;

}
void bellman(int s){
    int i, u, v, w;
    for(i=1; i<=n; i++) d[i] = INF;
    d[s] = 0;
    q.push(s);
    while(!q.empty()){
        u = q.front();
        q.pop();
        for(unsigned j=0; j<gf[u].size(); j++){
            v = gf[u][j].first; w = gf[u][j].second;
            if(d[v]>d[u]+w){
                d[v] = d[u] + w;
                q.push(v);
            }
        }
    }

}
void afis(){
    int i, j;
    for(i=0; i<=k+1; i++){
        for(j=0; j<=k+1; j++)
            fout<<mat[i][j]<<' ';
        fout<<endl;
    }
}