最短k倍路——解题报告

来源:互联网 发布:淘宝卖家号出售平台 编辑:程序博客网 时间:2024/05/17 00:56

题意:求a点与b点间所有k的倍数长度的路径中最短的一条。

题解:先做一遍拓扑序,再spfa维护dis[i][j],i表示到第i个点,j表示该最短距离%k=j。

代码附上

#include<iostream>#include<stdio.h>#include<algorithm>#include<string.h>#include<math.h>using namespace std;const int INF=0x3f3f3f3f;int n,m,s,a,b;int hj[1005][1005],hk[1005][1005],c[1005],d[1005],g[1005];int f[1005][1005];int main(){scanf("%d%d%d%d%d",&n,&m,&s,&a,&b);a-=1;b-=1;int x,y,z;for(int i=0;i<m;i++){scanf("%d%d%d",&x,&y,&z);x-=1;y-=1;c[x]++;d[y]++;hj[x][c[x]]=z;hk[x][c[x]]=y; }  g[0]=n; int t=0; for(int i=0;i<n;i++) { if(d[i]==0)//入度为0,加到集合G;  { t++; g[t]=i;  }   }   int j=-1;  while(t<n)  {  j++;  x=g[j];  for(int i=1;i<=c[x];i++)  {  y=hk[x][i];  d[y]--;  if(d[y]==0)  {  t++;  g[t]=y;  }  }  }//拓扑   for(int i=0;i<n;i++)  {  for(int l=0;l<s;l++)  {  f[i][l]=INF;  }  }  for(int i=1;i<=n;i++)  {  if(g[i]==a)//找到起点   {  f[g[i]][0]=0;  j=i;  break;  }  }  j--;  int o;  while(g[j]!=b)  {  j++;x=g[j];for(int i=0;i<s;i++){if(f[x][i]<INF){for(int k=1;k<=c[x];k++){y=hk[x][k];z=hj[x][k];o=(z+i)%s;if(f[y][o]>f[x][i]+z)f[y][o]=f[x][i]+z;}}}  }//spfa   if(f[b][0]<INF)  cout<<f[b][0]<<endl;  else  cout<<endl; } 

0 0