Cod sursa(job #479077)

Utilizator freak93Adrian Budau freak93 Data 22 august 2010 15:55:49
Problema Gather Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include<fstream>
#include<vector>
#include<queue>

using namespace std;

const char iname[]="gather.in";
const char oname[]="gather.out";
const int maxn=752;
const int maxk=16;
const int maxp=(1<<maxk);
const long long inf=(1LL<<61)-1+(1LL<<61);

ifstream f(iname);
ofstream g(oname);

class muchie
{
    public:
    int x,d;
    long long c;
    muchie(int _x,int _d,long long _c):x(_x),d(_d),c(_c){}
    muchie():x(0),d(0),c(0){}
};

vector<muchie> E[maxn];
queue<int> Q;
int poz[maxk],k,n,been[maxn],biti[maxp],x,y,m,i,j,p;
long long dis[maxn],dist[maxk][maxk][maxk],dp[maxk][maxp],rez,c,d;

void BF(int x,int m)
{
    Q.push(poz[x]);
    for(int i=1;i<=n;++i)
        been[i]=0,dis[i]=inf;
    dis[poz[x]]=0;
    been[poz[x]]=1;
    while(!Q.empty())
    {
        int x=Q.front();
        Q.pop();
        been[x]=0;
        for(vector<muchie>::iterator it=E[x].begin();it!=E[x].end();++it)
            if((int)it->c>=m)
                if(dis[x]+it->d<dis[it->x])
                {
                    dis[it->x]=dis[x]+it->d;
                    if(been[it->x]==0)
                        been[it->x]=1,Q.push(it->x);
                }
    }
    for(int i=1;i<=k;++i)
        dist[x][i][m]=dis[poz[i]];
}

long long calc(int x,int y)
{
    if(dp[x][y]!=inf)
        return dp[x][y];
    for(int i=0;i<=k;++i)
        if((i==0&&biti[y]==1)||(i&&i!=x&&((1<<i-1)&y)&&dist[i][x][biti[y]-1]!=inf))
        {
            calc(i,y-(1<<x-1));
            if(dp[i][y-(1<<x-1)]!=inf-1)
                dp[x][y]=min(dp[x][y],dp[i][y-(1<<x-1)]+dist[i][x][biti[y]-1]*biti[y]);
        }
    if(dp[x][y]==inf)
        return dp[x][y]=inf-1;
    return dp[x][y];
}

int main()
{
    f>>k>>n>>m;
    for(i=1;i<=k;++i)
        f>>poz[i];
    for(i=1;i<=m;++i)
        f>>x>>y>>d>>c,E[x].push_back(muchie(y,d,c)),E[y].push_back(muchie(x,d,c));

    for(i=1;i<=k;++i)
        for(j=1;j<=k;++j)
            BF(i,j);

    poz[0]=1;
    BF(0,0);

    for(i=1;i<=k;++i)
        for(j=1;j<(1<<k);++j)
            dp[i][j]=inf;
    dp[0][0]=0;

    for(i=1;i<=(1<<k);++i)
        biti[i]=biti[i>>1]+(i&1);

    rez=inf;
    for(i=1;i<=k;++i)
        rez=min(rez,calc(i,(1<<k)-1));
    g<<rez<<"\n";
}