D - Silver Cow Party

题目链接:https://cn.vjudge.net/contest/289568#problem/D
One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1…N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of time to traverse.

Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow’s return route might be different from her original route to the party since roads are one-way.

Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?
Input
Line 1: Three space-separated integers, respectively: N, M, and X
Lines 2… M+1: Line i+1 describes road i with three space-separated integers: Ai, Bi, and Ti. The described road runs from farm Ai to farm Bi, requiring Ti time units to traverse.
Output
Line 1: One integer: the maximum of time any one cow must walk.
Sample Input
4 8 2
1 2 4
1 3 2
1 4 7
2 1 1
2 3 5
3 1 2
3 4 4
4 2 3
Sample Output
10
Hint
Cow 4 proceeds directly to the party (3 units) and returns via farms 1 and 3 (7 units), for a total of 10 time units.

题意:
编号为1~N的N个农场中每一头奶牛将参加x农场 (1<=x<=N)举行大型奶牛聚会。
这意味着奶牛是从自己的农场去到其它奶牛的农场,并且这个道路是单向连接成对的;
每个道路需要走时间Ti;

每头奶牛都必须走到聚会上,当聚会结束时,回到她的农场。但每头奶牛都很懒,会选择最短时间的最佳路线。所以返回的路线可能与他原来的不同;

问题是:找到任何一头奶牛必须行走的最长时间;

解题思路:一旦理解到题意说找最短时间的最佳路线,就知道用最短路算法合适这题。
然后就想到dijksltra,但这样还是不能解决问题。
因为,这里还有一个回来的路线和时间要考虑!!!,
所以,要置换矩阵的值,也就是交换map[i][j]与map[j][i]的值,这样再用dijksltra时,就能找出回来的最佳路线了。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define maxn 1010
int map[maxn][maxn],n;
int way[maxn],dis[maxn];
void dijkstra(int x)
{
    int visit[maxn],i,j,min,next=x;
    memset(visit,0,sizeof(visit));
    for(i=1; i<=n; ++i)
        dis[i]=map[x][i];//
    visit[x]=1;
    for(i=2; i<=n; ++i)
    {
        min=INF;
        for(j=1; j<=n; ++j)
        {
            if(!visit[j]&&dis[j]<min)
            {
                min=dis[j];
                next=j;
            }
        }
        visit[next]=1;
        for(j=1; j<=n; ++j)
        {
            if(!visit[j]&&dis[j]>dis[next]+map[next][j])
                dis[j]=dis[next]+map[next][j];
        }
    }
}
int main()
{
    int m,x,i,j,a,b,t;
    while(scanf("%d%d%d",&n,&m,&x)!=EOF)
    {
        for(i=1; i<=n; ++i)
        {
            for(j=1; j<=n; ++j)
            {
                if(i!=j)
                    map[i][j]=INF;
                else
                    map[i][j]=0;
            }
        }
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&t);
            if(t<map[a][b])
                map[a][b]=t;
        }
        dijkstra(x);//找到去聚会时的最佳路线
        for(i=1; i<=n; ++i)
            way[i]=dis[i];//赋予值保存
        int ans=0;
        for(i=1; i<=n; ++i) //置换矩阵的值,也就是交换map[i][j]与map[j][i]的值;实现很简单,主要再思想;
        {
            for(j=i+1; j<=n; ++j)
            {
                int cnt;
                cnt=map[j][i];
                map[j][i]=map[i][j];
                map[i][j]=cnt;
            }
        }
        dijkstra(x);//回来时的最佳路线;
        for(i=1; i<=n; ++i)
        {
            if(i!=x)
                ans=max(ans,way[i]+dis[i]);//比较每头牛去和回来的最佳选择;
        }
        printf("%d\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43516113/article/details/89159617