题目意思很简单,就是让你求两天最短路中共同的公共点的最大个数

可以这样理解: 

  1.  我们假设存在2组数据 v0,u0,v1,u1; 
  2.  用path[i][j] 代表 从点i到点j最短路上最多有多少个点! 
  3.  那么 edge[v0][i]+edge[i][j]+edge[j][u0]=edge[v0][u0] 不就表示i到j的最短路为 v0到u0最短路的子路嘛; 
  4.  我们只需更新edge[i][j]中的最大值即可

代码如下。。。。

hdu 2833 dp+floyd_i++hdu 2833 dp+floyd_数据_02View Code
 1 #include<iostream>
 2 const int N=444;
 3 const int inf=10000000;
 4 using namespace std;
 5 
 6 int edge[N][N];
 7 int path[N][N];//用path[i]][j]来表示i->j的路径上最多有多少个点
 8 int n,m;
 9 
10 void floyd(){
11     for(int k=1;k<=n;k++){
12         for(int i=1;i<=n;i++){
13             if(i==k||edge[i][k]==inf)continue;
14             for(int j=1;j<=n;j++){
15                 if(i==k||j==k||edge[k][j]==inf)continue;
16                 if(edge[i][k]+edge[k][j]<edge[i][j]){
17                     edge[i][j]=edge[i][k]+edge[k][j];
18                     path[i][j]=path[i][k]+path[k][j]-1;
19                 }else if(edge[i][k]+edge[k][j]==edge[i][j]&&path[i][j]<path[i][k]+path[k][j]){    //此时i,j,k为最短路径上的点
20                     path[i][j]=path[i][k]+path[k][j]-1;
21                 }
22             }
23         }
24     }
25 }
26 
27 int solve(int v0,int u0,int v1,int u1){
28     int ans=0;
29     if(edge[v0][u0]>=inf||edge[v1][u1]>=inf)
30         return 0;
31     for(int i=1;i<=n;i++){
32         for(int j=1;j<=n;j++){
33             if(edge[v0][i]+edge[i][j]+edge[j][u0]==edge[v0][u0]&&
34                 edge[v1][i]+edge[i][j]+edge[j][u1]==edge[v1][u1]){
35                     ans=ans>path[i][j]?ans:path[i][j];
36             }
37         }
38     }
39     return ans;
40 }
41 
42 
43 int main(){
44     while(scanf("%d%d",&n,&m)!=EOF){
45         if(n==0&&m==0)break;
46         for(int i=1;i<=n;i++){
47             edge[i][i]=0,path[i][i]=1;
48             for(int j=i+1;j<=n;j++){
49                 edge[i][j]=edge[j][i]=inf;
50                 path[i][j]=path[j][i]=2;
51             }
52         }
53         int x,y,s;
54         for(int i=1;i<=m;i++){
55             scanf("%d%d%d",&x,&y,&s);
56             if(edge[x][y]>s){
57                 edge[x][y]=edge[y][x]=s;
58             }
59         }
60         floyd();
61         int v0,v1,u0,u1;
62         scanf("%d%d%d%d",&v0,&u0,&v1,&u1);
63         int ans=solve(v0,u0,v1,u1);
64         printf("%d\n",ans);
65     }
66     return 0;
67 }

后来在网上看了,也可用记忆化搜索。。。