HDU5137 How Many Maos Does the Guanxi Worth (13广州现场赛K题 )--最短路问题

链接:click here

题意:从2~n-1这几个点中任意去掉一个点,使得从1到n的最短路径最大,如果任意去掉一个点1~n无通路输出Inf。

去年这道题现场是队友1A过的,感觉好NB,当时还不会最短路问题,只是脑子里大概有这么个印象,做了之发现数据比较水,今天看了一下Dijkstra 和Floyd,用两种算法实现了一下:

题目描述有点长,但是搞清楚了,就很容易了,因为数据实在很水,算是最短路入门训练的一道题了

Dijkstra 算法

(1)令S={源点s + 已经确定了最短路径的顶点vi}

(2) 对任一未收录的顶点v,定义dist[v]为s到v的最

短路径长度,但该路径仅经过S中的顶点。即路径  的最小长度

(3) 若路径是按照递增(非递减)的顺序生成的,则

(4)真正的最短路必须只经过S中的顶点

(5)每次从未收录的顶点中选一个dist最小的收录(贪心)

(6)增加一个v进入S,可能影响另外一个w的dist值!

(7)dist[w] = min{dist[w], dist[v] + <v,w>的权重}

代码:

/*单源最短路问题(Dijkstra),适合没有负边的情况下,在Bellman-Ford算法中,如果d[i]还不是最短距离的话,
那么即使进行d[j]=d[i]+(从i到j的边的权值)的更新,d[j]也不会变成最短距离,而且,即使d[i]没有变化,
每一次循环也要检查一遍从i 出发的所有边,这显然是浪费时间的,因此,相对Bellman-Ford做了如下修改:
(1) 找到最短距离已经确定的顶点,从他出发更新相邻顶点的最短路径。(2) 不再考虑(1) 情况。
那么 如何找“最短距离已经确定的顶点”?在最开始时,只有起点的最短距离是确定的,而在尚未使用的顶点中,距离d[i]最小的顶点就是
已经确定的顶点,这是因为由于不存在负边的情况,所以d[i]在以后的更新中不会减小,这就是算法的由来
*/
/* time :0ms
 #include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn_v=35;
int V,m;                         //顶点数
int cost[maxn_v][maxn_v];        //cost[u][v]表示边e=(u,v)的权值
int d[maxn_v];                   //顶点s出发的最短距离
bool used[maxn_v];               //已经使用过的图
void init()                      //初始化
{
    for(int i=0; i<maxn_v; i++)
        for(int j=0; j<maxn_v; j++)
        {
            if(i==j) cost[i][j]=0;
            else cost[i][j]=inf;
        }
}
void input()                     //将点,边存入图中
{
    int u,v,quan;
    for(int i=0; i<m; i++)
    {
        scanf("%d %d %d",&u,&v,&quan);
        cost[u][v]=cost[v][u]=quan; //因为是无向图,权值一样
    }
}
int dijkstra(int s)               //求出从s出发到各个顶点的最短距离
{
    for(int i=0; i<maxn_v; i++)
        d[i]=inf;               //d[0]=0,其他d[i]=Inf;
    memset(used,false,sizeof(used));
    used[s]=true;
    d[1]=0;
    while(true)
    {
        int v=-1;
        for(int u=0; u<V; u++) //尚未使用过的顶点中选择一个距离最小的点
        {
            if(!used[u] &&(v==-1||d[u]<d[v]))
                v=u;
        }
        if(v==-1) break;
        used[v]=true;
        for(int u=1; u<=V; u++)
            d[u]=min(d[u],d[v]+cost[v][u]);
    }
    return d[V];
}
void solve()
{
    int ans=-1;
    for(int i=2; i<V; i++)
    {
        int t=dijkstra(i);
        if(t==inf)           //不符合
        {
            printf("Inf\n");
            return ;
        }
        else ans=max(ans,t); //依次更新
    }
    printf("%d\n",ans);
}
int main()
{
    while(~scanf("%d %d",&V,&m),V+m)
    {
        init();
        input();
        solve();
    }
    return 0;
}

/*Floyd - Warshall算法
   求解所有两点间的最短路的问题叫做任意两点间的最短路问题, 用Dp的思想来模拟一下过程:
   只使用顶点0~ k 的和i,j的情况下,记录i 到j 的最短路径为 d[k+1][i][j],k=-1时,认为只使用了i,j
   所以d[0][i][j]=cost[i][j]; 接下来把只使用顶点0~k的问题归纳为到只使用0~k-1上。
   只使用0~k时,分i到j的最短路为经过顶点k和不经过顶点k两种问题来讨论。
   不经过的情况下:
                 d[k][i][j]=d[k-1][i][j],
    经过的情况下:
                 d[k][i][j]=d[k-1][i][k]+d[k-1][k][j];
    结合起来就是:d[k][i][j]=min(d[k-1][i][j],d[k-1][i][k]+d[k-1][k][j]);
    可以在O(n^3)的时间复杂度里求解所有两点间的最短距离,跟Dijkstra 算法比较,Floyd - Warshall
    可以处理边是负数的情况,而要判断图中是否有负圈,只需检查是否存在d[i][i]是负数的顶点就可以。
*/
/*time:15ms
 #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 35;
const int Inf = 1e8;
int V;                     //顶点数
int m, D[N][N];
int  G[N][N];              //G[u][v] 表示边e=(u,v)的权值(不存在时设为INF,记G[i][i]=0;)
int solve(int x)
{
    for(int i=1; i<=V; i++)
    {
        for(int j=1; j<=V; j++)
        {
            if(i==x||j==x)    G[i][j]=Inf;
            else    G[i][j]=D[i][j];
        }
    }
    for(int k=1; k<=V; k++)
    {
        for(int i=1; i<=V; i++)
        {
            for(int j=1; j<=V; j++)
                G[i][j]=min(G[i][j],G[i][k]+G[k][j]);
        }
    }
    return G[1][V];
}
void input()
{
    for(int i=1; i<=V; i++)
    {
        for(int j=1; j<=V; j++)
            D[i][j]=(i==j)?0:Inf;
    }
}
void init()
{
    for(int i=0; i<m; i++)
    {
        int u,v,quan;
        scanf("%d%d%d",&u,&v,&quan);
        D[u][v]=min(D[u][v],quan);
        D[v][u]=D[u][v];
    }
}
void output()
{
    int ans=0;
    for(int i=2; i<V; i++)
    {
        ans=max(ans,solve(i));
    }
    if(ans==Inf) puts("Inf");
    else    printf("%d\n", ans);
}
int main()
{
    while(~scanf("%d%d",&V,&m),V+m)
    {
        input();
        init();
        output();
    }
    return 0;
}
时间: 2024-10-27 07:33:20

HDU5137 How Many Maos Does the Guanxi Worth (13广州现场赛K题 )--最短路问题的相关文章

HDU5137 How Many Maos Does the Guanxi Worth(枚举+dijkstra)

How Many Maos Does the Guanxi Worth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)Total Submission(s): 760    Accepted Submission(s): 290 Problem Description "Guanxi" is a very important word in Chinese. It

HDU 5137 How Many Maos Does the Guanxi Worth (14广州 Floyd 最短路)

How Many Maos Does the Guanxi Worth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 468    Accepted Submission(s): 164 Problem Description "Guanxi" is a very important word in Chinese. I

ACM学习历程——HDU5137 How Many Maos Does the Guanxi Worth(14广州10题)(单源最短路)

Problem Description "Guanxi" is a very important word in Chinese. It kind of means "relationship" or "contact". Guanxi can be based on friendship, but also can be built on money. So Chinese often say "I don't have one ma

hdu5137 How Many Maos Does the Guanxi Worth(单源最短路径)

题目链接:点击打开链接 题目描述:现在有一张关系网,网中有n个结点标号为1-n,有m个关系,每个关系之间有一个权值.问从2-n-1中任意去掉一个结点之后,从1-n的距离中所有最小值的最大值为多少? 解题思路:多次调用Dijkstra即可,每次标记那个结点不通即可 代码: #include <cstdio> #include <queue> #include <cstring> #define MAXN 31 #define MAXE 1010 #define INF 1

How Many Maos Does the Guanxi Worth

How Many Maos Does the Guanxi Worth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others)Total Submission(s): 864    Accepted Submission(s): 329 Problem Description "Guanxi" is a very important word in Chinese. It

hdu 5137 How Many Maos Does the Guanxi Worth(dijkstra &amp;&amp; floyd)

How Many Maos Does the Guanxi Worth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 853    Accepted Submission(s): 326 Problem Description "Guanxi" is a very important word in Chinese. I

HDU 5137 How Many Maos Does the Guanxi Worth(暴力+spfa)

题目大意:给你一个关系图,让你再删除一个点之后(除了1,和n).让你求出来从1到n的最短路的最大值,如果不可达输出Inf. 解题思路:题意也说了,就是暴力枚举点,然后跑n-2次spfa求出来一个最大值就可以了. How Many Maos Does the Guanxi Worth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 4

hdoj 5137 How Many Maos Does the Guanxi Worth 【枚举删点 + 最短路】

How Many Maos Does the Guanxi Worth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 512000/512000 K (Java/Others) Total Submission(s): 847    Accepted Submission(s): 322 Problem Description "Guanxi" is a very important word in Chinese. I

[ACM] HDU 5137 How Many Maos Does the Guanxi Worth(去掉一个点使得最短路最大化)

How Many Maos Does the Guanxi Worth Problem Description "Guanxi" is a very important word in Chinese. It kind of means "relationship" or "contact". Guanxi can be based on friendship, but also can be built on money. So Chinese