Description
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
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
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
题目大意:有n头奶牛分别在n个农场,农场之间有m条单向道路,每条道路有一个权值,现在要在农场x举办一个聚会,要我们帮忙算出所有奶牛从各自农场出发到达x并且再次返回各自农场的时间。
思路:题目是要求所有奶牛都返回各自农场的时间,首先每头牛都必须走最短的路才能使的花费的最长时间最短,所以求出每一头牛出发再返回所花费的最小时间,再取一个最大值即是所有奶牛都返回的时间了
第一次的代码思路虽然过了但是花费了较多的时间,第二次做了一部分的优化,从第一份代码的672MS改进到了第二份代码的47MS,希望优化的思路对大家有所帮助吧~
code1:
1 #include<iostream> 2 #include<algorithm> 3 #include<vector> 4 #include<queue> 5 using namespace std; 6 const int INF = 0x3f3f3f3f; 7 const int maxn = 1010; 8 struct node{ 9 int to, cost; 10 node() {} 11 node(int a, int b) :to(a), cost(b) {} 12 }; 13 vector<node>e[maxn]; 14 int dis[maxn], vis[maxn], f[maxn]; 15 int n, m, x; 16 void SPFA(int s) 17 { 18 for (int i = 0; i <= n; i++) { 19 vis[i] = 0; f[i] = 0; 20 dis[i] = INF; 21 } 22 queue<int>Q; 23 dis[s] = 0; Q.push(s); 24 vis[s] = 1; f[s]++; 25 while (!Q.empty()) { 26 int t = Q.front(); Q.pop(); vis[t] = 0; 27 for (int i = 0; i < e[t].size(); i++) { 28 int tmp = e[t][i].to; 29 if (dis[tmp] > dis[t] + e[t][i].cost) { 30 dis[tmp] = dis[t] + e[t][i].cost; 31 if (!vis[tmp]) { 32 vis[tmp] = 1; 33 Q.push(tmp); 34 if (++f[tmp] > n)return; 35 } 36 } 37 } 38 } 39 } 40 int main() 41 { 42 ios::sync_with_stdio(false); 43 while (cin >> n >> m >> x) { 44 for (int a, b, c, i = 1; i <= m; i++) { 45 cin >> a >> b >> c; 46 e[a].push_back(node(b, c)); 47 } 48 int ans = 0; 49 for (int i = 1; i <= n; i++) { 50 int tmp = 0; 51 if (i != x) { 52 SPFA(i); 53 tmp += dis[x]; 54 SPFA(x); 55 tmp += dis[i]; 56 } 57 ans = max(ans, tmp); 58 } 59 cout << ans << endl; 60 } 61 return 0; 62 }
code2:由于是单向边,正向过去第一遍SPFA可以求得点x到其他所有点的最短距离,之后将每一条边反转,再求一次SPFA,现在可以求得除x的所有点到x的最短距离,两次最短距离之和就是其他各点到x并且返回到各自位置的最短距离。
#include<iostream> #include<algorithm> #include<cstdio> #include<vector> #include<queue> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 1010; struct node{ int to, cost; node() {} node(int a, int b) :to(a), cost(b) {} }; struct Task { int x, y, z; }rs[100005]; vector<node>e[maxn]; int dis[maxn], vis[maxn], f[maxn]; int n, m, x; void SPFA(int s) { for (int i = 0; i <= n; i++) { vis[i] = 0; f[i] = 0; dis[i] = INF; } queue<int>Q; dis[s] = 0; Q.push(s); vis[s] = 1; f[s]++; while (!Q.empty()) { int t = Q.front(); Q.pop(); vis[t] = 0; for (int i = 0; i < e[t].size(); i++) { int tmp = e[t][i].to; if (dis[tmp] > dis[t] + e[t][i].cost) { dis[tmp] = dis[t] + e[t][i].cost; if (!vis[tmp]) { vis[tmp] = 1; Q.push(tmp); if (++f[tmp] > n)return; } } } } } int main() { //ios::sync_with_stdio(false); while (~scanf("%d%d%d",&n,&m,&x)) { for (int i = 1; i <= n; i++)e[i].clear(); for (int a, b, c, i = 1; i <= m; i++) { scanf("%d%d%d", &rs[i].x, &rs[i].y, &rs[i].z); e[rs[i].x].push_back(node(rs[i].y, rs[i].z)); } int ans = 0, tmp[maxn]; SPFA(x); for (int i = 1; i <= n; i++) { tmp[i] = dis[i]; e[i].clear(); } for (int i = 1; i <= m; i++) e[rs[i].y].push_back(node(rs[i].x, rs[i].z)); SPFA(x); for (int i = 1; i <= n; i++) { if (i != x) { tmp[i] += dis[i]; ans = max(ans, tmp[i]); } } printf("%d ",ans); } return 0; }