zoukankan      html  css  js  c++  java
  • 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 }

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

  • 相关阅读:
    Linux 安装SonarQube
    Linux 安装postgresql
    如何为chrome浏览器设置socks5代理
    echarts tab切换宽度变为100px解决方案
    将url参数转为对象
    一行js代码实现时间戳转时间格式
    解决问题的方法论
    李笑来的幻灯课
    随便写写(最近更新于2021/07/18早)
    谈谈装系统这件事
  • 原文地址:https://www.cnblogs.com/wally/p/2889427.html
Copyright © 2011-2022 走看看