题意:找所有奶牛花费最小值的最大,注意该图为单向图 思路:有点类似于多源最短路,可以用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; }