Cod sursa(job #927042)

Utilizator SebiSebiPirtoaca George Sebastian SebiSebi Data 25 martie 2013 15:43:45
Problema Gather Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.25 kb
#include<iostream>
#include<fstream>
#include<vector>
#include<queue>
#include<string.h>
using namespace std;

#define NMAX 751
#define KMAX 16
#define INF 1LL<<60

struct PRIS {
    int y,c,d;
};

vector <PRIS> v[NMAX];
long long d[1<<KMAX][KMAX],dist[KMAX][KMAX+1][KMAX],BF[NMAX];
int inq[NMAX],loc[KMAX],n,k;
queue <int> q;


inline PRIS MP(int _y, int _c, int _d)
{
    PRIS x;
    x.y=_y;
    x.c=_c;
    x.d=_d;
    return x;
}

inline long long minim(long long a, long long b)
{
    if(a<=b)
        return a;
    return b;
}

inline int BIT(int x, int nr)
{
    return ((x & (1<<nr)) != 0);
}

void bellman_ford(int start, int dmax)
{
    int i,nod;
    memset(inq,0,sizeof(inq));
    for(i=0;i<=n;i++)
        BF[i]=INF;
    BF[start]=0;
    inq[start]=1;
    q.push(start);
    while(q.empty()==0) {
        nod=q.front();
        q.pop();
        inq[nod]=0;
        for(vector <PRIS> :: iterator it=v[nod].begin();it!=v[nod].end();it++)
            if(it->d>=dmax && BF[it->y]>(0LL+BF[nod]+it->c)) {
                BF[it->y]=0LL+BF[nod]+it->c;
                if(inq[it->y]==0) {
                    q.push(it->y);
                    inq[it->y]=1;
                }
            }
    }
}

long long dp(int S, int p, int nrd)
{
    int i;
    if(S!=(1<<p) && S && d[S][p]==0) {
        d[S][p]=INF;
        for(i=0;i<=k;i++)
            if(BIT(S,i) && dist[p][nrd-1][loc[i]]!=INF && p!=i)
                d[S][p]=minim(d[S][p],0LL+dp(S-(1<<p),i,nrd+1)+1LL*nrd*dist[p][nrd-1][loc[i]]);
    }
    return d[S][p];
}

int main ()
{
    int m,x,y,c,d,i,j,l;
    long long sol;
    ifstream f("gather.in");
    ofstream g("gather.out");
    f>>k>>n>>m;
    k--;
    for(i=0;i<=k;i++)
        f>>loc[i];
    for(i=1;i<=m;i++) {
        f>>x>>y>>c>>d;
        v[x].push_back(MP(y,c,d));
        v[y].push_back(MP(x,c,d));
    }
    f.close();
    for(i=0;i<=k;i++)
        for(j=0;j<=KMAX;j++) {
            bellman_ford(loc[i],j);
            for(l=0;l<=n;l++)
                dist[i][j][l]=BF[l];
    }
    sol=INF;
    bellman_ford(1,0);
    for(i=0;i<=k;i++)
        sol=minim(sol,0LL+dp((1<<(k+1))-1,i,2)+BF[loc[i]]);
    g<<sol;
    while(sol==INF);
    g.close();
    return 0;
}