Cod sursa(job #1127885)

Utilizator mircea.dobreanuMircea Dobreanu mircea.dobreanu Data 27 februarie 2014 14:10:41
Problema Ubuntzei Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.02 kb
#include<fstream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
const int INF=(1<<30)-1;
const int MAXN=2001;
const int MAXK=18;
int n,m,k,DR_MIN=INF;
int d[MAXN],c[MAXK],COST[MAXK][MAXK];
int DP[1<<MAXK][MAXK];
vector<pair<int,int> > G[MAXN];
class Compare
{
    public:
    bool operator() (const int& a, const int& b)
    {
        return d[a]>d[b];
    }
};
priority_queue<int,vector<int>,Compare> PQ;
void read()
{
    int x,y,w;
    ifstream fin("ubuntzei.in");
    fin>>n>>m>>k;
    c[0]=1; c[k+1]=n;
    for (int i=1; i<=k; ++i)
        fin>>c[i];
    for (int i=1; i<=m; ++i)
    {
        fin>>x>>y>>w;
        G[x].push_back(make_pair(y,w));
        G[y].push_back(make_pair(x,w));
    }
    fin.close();
}
void write()
{
    ofstream fout("ubuntzei.out");
    fout<<DR_MIN<<'\n';
    fout.close();
}
void init(int src)
{
    for (int i=0; i<=n; d[i]=INF, ++i);
    d[src]=0;
}
void dijkstra(int src)
{
    init(src);
    PQ.push(src);
    int u,v,w;
    while (!PQ.empty())
    {
        u=PQ.top();
        PQ.pop();
        for (vector<pair<int,int> >::iterator it=G[u].begin(); it!=G[u].end(); ++it)
        {
            v=(*it).first;
            w=(*it).second;
            if (d[v]>d[u]+w)
            {
                d[v]=d[u]+w;
                PQ.push(v);
            }
        }
    }
}
void solve()
{
    //CONSTRUIREA MATRICEI GRAFULUI COMPLET
    int i,j,v;
    k+=2;
    for (i=0; i<k; ++i)
    {
        dijkstra(c[i]);
        for (j=0; j<k; ++j)
            COST[i][j]=d[c[j]];
    }
    COST[0][0]=INF;
    //CAZUL DE BAZA si initializarea
    for (i=0; i<(1<<k); ++i)
        for (j=0; j<k; ++j)
            DP[i][j]=INF;

    DP[1][0]=0;

    //RECURENTA
    for (i=0; i<(1<<k); ++i)
        for (j=0; j<k; ++j)
            if (i&(1<<j))
                for (v=0; v<k; ++v)
                    if (i&(1<<v))
                        DP[i][j]=min(DP[i][j], DP[i ^ (1<<j)][v]+COST[v][j]);
    //CALCULUL SOLUTIEI
    DR_MIN=DP[(1<<k)-1][k-1];
}
int main()
{
    read();
    solve();
    write();
    return 0;
}