hdu2833(2009多校第一场) 两条路最多交点
用floyd处理最短路的同时更新路上最多节点。
然后枚举重合线段,只要符合两条都是最短路即可更新ans。
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 int dis[315][315],num[315][315]; 6 int main() 7 { 8 int n,m,k,i,j,v,x,y,a,b,c,d,tmp,ans; 9 while (~scanf("%d%d",&n,&m)&&(n||m)) 10 { 11 memset(num,0,sizeof(num)); 12 for (i=1;i<=n;i++) 13 for (j=1;j<=n;j++) 14 dis[i][j]=(i==j?0:100000000); 15 for (i=1;i<=m;i++) 16 { 17 scanf("%d%d%d",&x,&y,&v); 18 if (v>dis[x][y]) continue; 19 dis[x][y]=dis[y][x]=v; 20 num[x][y]=num[y][x]=1; 21 } 22 for (k=1;k<=n;k++) 23 for (i=1;i<=n;i++) 24 for (j=1;j<=n;j++) 25 { 26 tmp=dis[i][k]+dis[k][j]; 27 if (tmp>dis[i][j]) continue; 28 if (tmp==dis[i][j]) { 29 num[i][j]=max(num[i][j],num[i][k]+num[k][j]); 30 continue; 31 } 32 dis[i][j]=tmp; 33 num[i][j]=num[i][k]+num[k][j]; 34 } 35 ans=-1; 36 scanf("%d%d%d%d",&a,&b,&c,&d); 37 for (i=1;i<=n;i++) 38 for (j=1;j<=n;j++) 39 { 40 if (num[i][j]<ans) continue; 41 if (dis[a][i]+dis[i][j]+dis[j][b]!=dis[a][b]) continue; 42 if (dis[c][i]+dis[i][j]+dis[j][d]!=dis[c][d]) continue; 43 ans=num[i][j]; 44 } 45 printf("%d\n",ans+1); 46 } 47 return 0; 48 }