hdu2833(Floyd)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2833

求两个人的起点和终点的最短路径上最多能有多少个相同点。

用Floyd求出任意两点之间的最短路。

假设做完Floyd的数组为A,则有如下性质。A[a][b]==A[a][i]+A[i][j]+A[j][b];如我们在做Floyd时同时计算出任意两点之间的最短路上经过的点的个数。则在作完Floyd之后,枚举前面公式中的i和j。就能得出结果。

至于为什么公共点一定会组成顺序一样的相同路径,可用反证法证明。

#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;
#define INF 10000000
int A[305][305],B[305][305];
int N,M;
void Floyd()
{
    for(int k=1;k<=N;k++)
    {
        for(int i=1;i<=N;i++)
        {
            for(int j=1;j<=N;j++)
            {
                if(A[i][j]>A[i][k]+A[k][j])
                {
                    A[i][j]=A[i][k]+A[k][j];
                    B[i][j]=B[i][k]+B[k][j];
                }
                else if(A[i][j]==A[i][k]+A[k][j]&&B[i][j]<B[i][k]+B[k][j])
                {
                    B[i][j]=B[i][k]+B[k][j];
                }
            }
        }
    }
}
void Init()
{
    for(int i=1;i<=N;i++)
    {
        for(int j=1;j<=N;j++)
        {
            A[i][j]=INF;
        }
        A[i][i]=0;
    }
    memset(B,0,sizeof(B));
}
int main()
{
    int a,b,c,d;
    int s,e,w;
    while(scanf("%d%d",&N,&M))
    {
        if(N==0&&M==0)
            break;
        Init();
        while(M--)
        {
            scanf("%d%d%d",&s,&e,&w);
            if(A[s][e]<w)
                continue;
            A[s][e]=w;
            A[e][s]=w;
            B[s][e]=1;//保存的是不算终点的情况下,所经历的个数。若要保存算上终点时的个数,则在Floyd中的B数组更新时要减去1,不然会多计算一边k点。
            B[e][s]=1;
        }
        scanf("%d%d%d%d",&a,&b,&c,&d);
        Floyd();
        int ans=-1;//必须初始化为-1,否则在没有公共点时,本应该输出0,却会输出1.
        for(int i=1;i<=N;i++)
        {
            for(int j=1;j<=N;j++)
            {
                if((A[a][b]==A[a][i]+A[i][j]+A[j][b])
                   &&(A[c][d]==A[c][i]+A[i][j]+A[j][d])
                   &&(ans<B[i][j]))
                    ans=B[i][j];
            }
        }
        cout<<ans+1<<endl;//要加上公共路径中的终点,所以要加1.
    }
    return 0;
}

  

时间: 2024-11-03 03:33:20

hdu2833(Floyd)的相关文章

HDU2833 最短路 floyd

WuKong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1800    Accepted Submission(s): 670 Problem Description Liyuan wanted to rewrite the famous book "Journey to the West" ("Xi You J

HDU2833 WuKong(floyd + dp)经典

WuKong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1429    Accepted Submission(s): 517 Problem Description Liyuan wanted to rewrite the famous book "Journey to the West" ("Xi You

AtCoder Beginner Contest 074 D - Restoring Road Network(Floyd变形)

题目链接:点我点我 题意:给出一个最短路的图,询问是否正确,如果正确的话,输出遍历所有点的最短路径和. 题解:判断是否正确的,直接再一次Floyd,判断是否会有A[i][k]+A[k][j]<A[i][j](通过中间点k使得两点间距离更短),如果有的话,直接输出-1. 要遍历到所有道路,并且路径和最小,我们可以尽可能用用中间点的路径(A[i][k]+A[k][j]==A[i][j]),这样本来遍历两个点,就可以遍历3个点了, 最后加的时候记得不要从重复加,从最小点往后加,不要再往前加,不然就重复

floyd算法--一个人的旅行

2017-07-27 22:37:32 writer:pprp 题目如下: 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历, 还可以看美丽的风景--草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信, 去北京探望孟姜女--眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训

UVA104Arbitrage(floyd最短路)

UVA104Arbitrage 题目大意: 给你两两国家之间的汇率,要求你从任何一个国家出发,身上带着1(单位不明),然后回到这个国家时,身上的钱能够> 1.01.并且如果这样的路径有多条的话,希望的到的是最短的路径,并且还有要求你输出这个最短的路径. 解题思路: 利用floyd可以求出旅游任何两个国家的可以得到的最大的金钱,可是无法获得最短的路径,最短路径的意思是中转的国家数尽量少.因此需要再加上一维来标记国家i到j,中间经过了p个中间的国家到达(包括i).那么G[i][j][p] = max

Six Degrees of Cowvin Bacon (poj 2139 最短路Floyd)

Language: Default Six Degrees of Cowvin Bacon Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3288   Accepted: 1529 Description The cows have been making movies lately, so they are ready to play a variant of the famous game "Six Degrees

【最短路】求两点间最短路的Floyd算法及其matlab实现

代码来源:<图论算法及其matlab实现>(北京航空航天出版社) P22 此代码返回第一个点和最后一个点之间最短路径,以及最短路径的长度. 代码如下: 1 function [P,u ] = Floyd(W) 2 %W表示权值矩阵 3 %P表示最短路径 4 %u表示最短路的权和 5 n=length(W); 6 U=W; 7 m=1; 8 9 while m<=n %判断是否满足停止条件 10 for i=1:n 11 for j=1:n 12 if U(i,j)>U(i,m)+U

POJ - 2253 Frogger(Floyd最短路+预处理)

题目链接:http://poj.org/problem?id=2253 题意:青蛙要从点1到点2,给出各点的坐标,如果点A到点B可以通过A->C,C->B,A到B的距离可以用A->C和C-B中较长的一边代替(如果A直接到B更短的话就不用了),求点1到点2的最短距离. 题解:本来想用dijkst,但是想想就200的数据量,直接Floyd岂不美滋滋.先预处理一下各点之间的距离.因为取两条边中较长的那条边,所以转移的话,那转移的两条边都要比原来的短才可以. 值得注意的是用C的格式输入的时候要用

Floyd算法 - 最短路径

2017-07-27 22:21:04 writer:pprp 该算法的本质是动态规划,形式简单,复杂度高为O(n^3): d[i][j] = max(d[i][k]+d[k][j],d[i][j]); 采用的基本手段是松弛 适用:解决多源最短路径问题 代码如下: #include <iostream> using namespace std; const int maxn = 200; int n,s,t; int a[maxn+1][maxn+1]; void init() { int m