hdu 2833 dp+floyd

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

可以这样理解: 

  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]中的最大值即可

代码如下。。。。

View 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 }

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

 

 

 

你可能感兴趣的:(floyd)