当前位置: 代码迷 >> 综合 >> POJ 3268 Silver Cow Party 最短路
  详细解决方案

POJ 3268 Silver Cow Party 最短路

热度:4   发布时间:2024-02-26 14:58:05.0
DescriptionOne 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?InputLine 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.
OutputLine 1: One integer: the maximum of time any one cow must walk.
Sample Input4 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 Output10
HintCow 4 proceeds directly to the party (3 units) and returns via farms 1 and 3 (7 units), for a total of 10 time units.
SourceUSACO 2007 February Silver

题意:找所有奶牛花费最小值的最大,注意该图为单向图
思路:有点类似于多源最短路,可以用floyd算法求解。但是时间复杂度是O(n^3)会超时。但有一点的是,最大花费一定同时发生在同一条奶牛身上,所以可以反向建图,做两遍dijkstra,一遍求从起点到终点,一遍从终点到起点,花费大小与方向无关(路径是确定的)

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue> 
#include <cstring>
using namespace std;const int N = 10005;
#define INF 0x3f3f3f3f
typedef pair<int,int> PII;int dist1[N],dist2[N],n,m,x;
int h1[N],e1[N],ne1[N],w1[N],idx1;
int h2[N],e2[N],ne2[N],w2[N],idx2;
bool st[N];void add1(int a,int b,int c)
{
    w1[idx1] = c,e1[idx1] = b,ne1[idx1] = h1[a],h1[a] = idx1++;
}void add2(int a,int b,int c)
{
    w2[idx2] = c,e2[idx2] = b,ne2[idx2] = h2[a],h2[a] = idx2++;
}
//稀疏图,用堆来优化dijkstra,时复杂度 O (n log m)
void work(int s,int dist[],int h[],int e[],int w[],int ne[])
{
    dist[s] = 0;priority_queue<PII,vector<PII>,greater<PII> > heap;PII u;u.first = 0,u.second = s;heap.push(u);while(heap.size()){
    PII t = heap.top();heap.pop();int ver = t.second;if(st[ver])	continue;st[ver] = true;for(int i = h[ver]; i != -1 ; i = ne[i]){
    int j = e[i];if(dist[j] > dist[ver] + w[i]){
    dist[j] = dist[ver] + w[i];u.first = dist[j],u.second = j;heap.push(u);}}}
}int main()
{
    scanf("%d %d %d",&n,&m,&x);memset(h1,-1,sizeof h1);memset(h2,-1,sizeof h2);memset(dist1,0x3f,sizeof dist1);memset(dist2,0x3f,sizeof dist2);for(int i = 0; i < m; i++){
    int a,b,c;scanf("%d %d %d",&a,&b,&c);add1(a,b,c);add2(b,a,c);}memset(st,false,sizeof st);work(x,dist1,h1,e1,w1,ne1);memset(st,false,sizeof st);work(x,dist2,h2,e2,w2,ne2);//遍历求最大花费int res = 0;for(int i = 1; i <= n; i++)	if(dist1[i] != INF && dist2[i] != INF)res = max(res,dist1[i] + dist2[i]);cout << res << endl;	return 0;
}