记录编号 403429 评测结果 AAAAAAAAAA
题目名称 [HZOI 2016]在路上 最终得分 100
用户昵称 GravatarHzoi_Ivan 是否通过 通过
代码语言 C++ 运行时间 2.404 s
提交时间 2017-05-10 11:31:06 内存使用 187.47 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define N 20005
using namespace std;
int e=1,head[N],dis[25][N],n,m,k,a[22];
int bit[23],c[22],f[1<<21][22],ans=0x7fffffff;
bool bo[N];
struct edge{
  int v,w,next;
}ed[800005];
void add(int u,int v,int w)
{
     ed[e].v=v;
     ed[e].w=w;
     ed[e].next=head[u];
     head[u]=e++;
}
void spfa(int x)
{
     queue<int > q;
     for(int i=1;i<=n;i++)dis[x][i]=0x7ffffff;
     dis[x][x]=0;
     bo[x]=1; 
     q.push(x);
     while(!q.empty())
     {
       int y=q.front(); q.pop(); bo[y]=0;
       for(int i=head[y];i;i=ed[i].next)
       {
         int v=ed[i].v;
         if(dis[x][y]+ed[i].w<dis[x][v]){
           dis[x][v]=dis[x][y]+ed[i].w;
           if(!bo[v]){
             bo[v]=1; q.push(v);
           }
         }
       }
     }
     return ;
}
void dp()
{
     f[1][1]=0;
     for(int i=1;i<bit[k+1];i++)
       for(int pos=1;pos<=k+1;pos++)
         if(i&bit[pos-1]&&f[i][pos]!=1061109567)
           for(int j=2;j<=k+1;j++)
             if(!(i&(bit[j-1]))&&((i&c[j])==c[j]))
               f[i|bit[j-1]][j]=min(f[i|bit[j-1]][j],f[i][pos]+dis[pos][j]);
}
int main()
{
	freopen("atr.in","r",stdin);
	freopen("atr.out","w",stdout);
    memset(f,0x3f,sizeof(f));
    bit[0]=1;
    for(int i=1;i<=22;i++) bit[i]=bit[i-1]<<1;
    int aa,bb,cc;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=m;i++){
      scanf("%d%d%d",&aa,&bb,&cc);
      add(aa,bb,cc);
      add(bb,aa,cc);
    }
    scanf("%d",&m);
    for(int i=1;i<=k+1;i++)
      c[i]|=1;
    for(int i=1;i<=m;i++)
    {
      scanf("%d%d",&aa,&bb);
      c[bb]|=bit[aa-1];
      c[bb]|=c[aa];
    }
    for(int i=1;i<=k+1;i++)
      spfa(i);
    dp();
    for(int i=1;i<=k+1;i++)
      ans=min(ans,f[bit[k+1]-1][i]+dis[i][n]);
    printf("%d\n",ans);
}