描述
N个农场(1 ≤ N ≤ 1000)中的每一个都有一头奶牛,编号为 1.. N将参加在农场 # X(1 ≤ X ≤ N)举行的大型奶牛聚会。总共有M (1 ≤ M ≤ 100,000) 条单向(单向道路连接成对的农场;道路i需要T i (1 ≤ T i ≤ 100) 单位时间才能穿过。
每头奶牛必须步行去参加聚会,聚会结束后,回到她的农场。每头奶牛都很懒惰,因此会选择最短时间的最佳路线。由于道路是单向的,母牛的返回路线可能与她前往派对的原始路线不同。
在所有奶牛中,一头奶牛必须花多长时间去参加聚会和回来?
输入
第 1 行:三个空格分隔的整数,分别为:N、M和X
第 2 行.. M +1:第i +1 行用三个空格分隔的整数描述道路i : A i、B i和T i。所描述的道路从农场A i延伸到农场B i,需要T i个时间单位来穿越。
输出
第 1 行:一个整数:任何一头牛必须行走的最长时间。
样例输入
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
样例输出
10
提示
奶牛 4 直接前往派对(3 个单位)并通过农场 1 和 3(7 个单位)返回,总共 10 个时间单位。 一开始想着是从起点到x算一遍再加上x到起点算一遍加起来,然后果不其然,TLE了。。去洛谷对了一下是有两个样例TLE了,还不错哈哈,然后看了看网上的解决方案是先计算起点到x得到一个dis最短路数组,然后将dis存储到另一个数组way上,再将原地图转置,继续算一遍dijstra就好了,结尾把dis和way的数值加起来比较每个点的最大值即可#include<bits/stdc++.h> using namespace std; const int inf = 1e8+10; int ma[1005][1005]; int vis[1005]; int dis[1005],way[1005]; int n,m,x; void dijstra(int sx) { int pos=1,minn,sum=0; memset(vis,0,sizeof(vis)); for(int i=1;i<=n;i++)dis[i] = ma[sx][i]; vis[sx] = 1; dis[sx] = 0; for(int i=1;i<=n;i++) { minn = inf; for(int j=1;j<=n;j++) { if(vis[j]==0&&minn>dis[j]) { minn = dis[j]; pos = j; } } if(minn==inf)break; vis[pos] = 1; for(int j=1;j<=n;j++) { if(vis[j]==0&&dis[j]>minn+ma[pos][j]) { dis[j] = minn+ma[pos][j]; } } } } int main() { cin>>n>>m>>x; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j)ma[i][j] = 0; else ma[i][j] = inf; } for(int i=1;i<=m;i++) { int a,b,c; cin>>a>>b>>c; if(ma[a][b]>c) ma[a][b] = c; } dijstra(x); //先计算每个点到x的最短路 for(int i=1;i<=n;i++)way[i] = dis[i]; //把到x的最短路记录到way中 for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) { swap(ma[i][j],ma[j][i]);//逆置矩阵,就可以将单向图逆转 } dijstra(x);//这里就相当于是计算x到各个点的最短路 int ans = -1; for(int i=1;i<=n;i++) { ans = max(way[i]+dis[i],ans); } cout<<ans; return 0; }
标签:ma,int,pos,dijstra,1693,TZOJ,1005,奶牛,dis From: https://www.cnblogs.com/jyssh/p/16791536.html