Cod sursa(job #983018)

Utilizator stefanzzzStefan Popa stefanzzz Data 10 august 2013 17:23:03
Problema Gather Scor 70
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.08 kb
#include <fstream>
#include <vector>
#include <queue>
#define MAXN 755
#define MAXK 20
#define INF 2000000000000000000
#define MAXCOD 33000
using namespace std;
ifstream f("gather.in");
ofstream g("gather.out");

struct muchie{
    int nod,lg,maxd;};
struct el_pq{
    int nod,cod;
    long long dist;};
struct Comp{
    bool operator()(pair<int,long long> a,pair<int,long long> b){
        return a.second>b.second;}};
struct Comp2{
    bool operator()(el_pq a,el_pq b){
        return a.dist>b.dist;}};

int n,m,k,a,b,camera[MAXK],detinut[MAXN],nrd;
long long dmin[MAXK][MAXK][MAXK],dst[MAXN],dist2[MAXK][MAXCOD];
bool uz[MAXK];
muchie aux;
el_pq x;
vector<muchie> G[MAXN];
priority_queue< pair<int,long long>, vector< pair<int,long long> >, Comp> pq;
priority_queue<el_pq,vector<el_pq>,Comp2> hp;
pair<int,long long> p;

void djikstra(int a,int b);

int main(){
    int i,j;
    f>>k>>n>>m;
    for(i=1;i<=n;i++)
        detinut[i]=-1;
    for(i=0;i<k;i++){
        f>>camera[i];
        detinut[camera[i]]=i;}
    camera[k]=1;
    detinut[1]=k;
    for(i=1;i<=m;i++){
        f>>a>>b>>aux.lg>>aux.maxd;
        aux.nod=a;
        G[b].push_back(aux);
        aux.nod=b;
        G[a].push_back(aux);}
    for(i=0;i<=k;i++)
        for(j=0;j<k;j++)
            djikstra(i,j);
    for(i=0;i<=k;i++)
        for(j=0;j<(1<<k);j++)
            dist2[i][j]=INF;
    dist2[k][0]=0;
    x.nod=k;
    x.cod=x.dist=0;
    hp.push(x);
    while(1){
        x=hp.top();
        hp.pop();
        while(x.dist!=dist2[x.nod][x.cod]){
            x=hp.top();
            hp.pop();}
        if(x.cod==((1<<k)-1))
            break;
        a=x.nod;
        nrd=0;
        for(i=0;i<k;i++)
            if(x.cod&(1<<i)){
                uz[i]=1;
                nrd++;}
            else
                uz[i]=0;
        for(i=0;i<=k;i++){
            if(i==a||uz[i])
                continue;
            if(i<k)
                x.cod+=(1<<i);
            if(x.dist+dmin[a][nrd][i]<dist2[i][x.cod]){
                dist2[i][x.cod]=x.dist+dmin[a][nrd][i];
                x.nod=i;
                x.dist+=dmin[a][nrd][i];
                hp.push(x);
                x.dist-=dmin[a][nrd][i];}
            if(i<k)
                x.cod-=(1<<i);}}
    g<<x.dist<<'\n';
    f.close();
    g.close();
    return 0;}

void djikstra(int a,int b){
    int i,x=camera[a];
    for(i=1;i<=n;i++)
        dst[i]=INF;
    dst[x]=0;
    pq.push(make_pair(x,0));
    while(!pq.empty()){
        p=pq.top();
        pq.pop();
        while(!pq.empty()&&p.second>dst[p.first]){
            p=pq.top();
            pq.pop();}
        if(p.second>dst[p.first])
            break;
        x=p.first;
        for(i=0;i<G[x].size();i++){
            aux=G[x][i];
            if(aux.maxd<b)
                continue;
            if(p.second+aux.lg*(b+1)<dst[aux.nod]){
                dst[aux.nod]=p.second+aux.lg*(b+1);
                pq.push(make_pair(aux.nod,dst[aux.nod]));}}}
    for(i=1;i<=n;i++)
        if(detinut[i]!=-1)
            dmin[a][b][detinut[i]]=dst[i];}