1413: StarFarming [最短路]
时间限制: 1 Sec 内存限制: 128 MB提交: 360 解决: 47 统计
题目描述
星农(StarFarming)公司计划要给员工发路费津贴,发放的规则是这样的:1
到n-1
代表各个员工家的序号,n
代表公司。路费津贴只发给上班的最短路与回家的最短路的总路程最长的人。该市的路建造的有些奇怪,修路只修单行道,即只允许往某一个方向通行。
现在给你城市的有向图的地图,TLG请你帮忙计算谁能得到津贴,以及他上班和回家的总路程是多少。
输入
有多组测试数据。
每组第一行输入两个整数N
,M
。表示点的个数,与单行道的数量(可能有重复)
接下来m
行,每行输入三个整数x
,y
,z
。表示从x
到y
城市有一条单行道,距离为z
。
题目保证至少一人存在来回的路径。不存在的不发津贴(班都没法好好上还想要钱?!)
1≤N≤1000 1≤N≤1000
1≤M≤100000 1≤M≤100000
1≤x,y≤N 1≤x,y≤N
1≤z≤200 1≤z≤200
输出
对于每组数据,输出两个整数,分别表示获得津贴的人的序号以及总路程。(如果有多个人路程相同,取序号最小的)
样例输入
4 7
1 2 2
2 3 2
1 3 4
4 1 2
4 2 2
3 4 1
4 3 5
样例输出
1 7#include<stdio.h> #include<string.h> #include<algorithm> #include<set> using namespace std; int n,m,a[1005][1005],d[1005],vis[1005],d1[1005]; //题解写的我只能说醉了,俩函数,明明一个函数就能解决问题 const int inf=0xffffff; void dijkstra() { int sum=0,i,j,k,v,ans=0; for(i=1;i<=n;i++) { int u=0,min=inf; for(j=1;j<=n;j++) { if(vis[j]==0&&d[j]<min) { u=j; min=d[j]; } } vis[u]=1; if(u==0) { return; } for(v=1;v<=n;v++) { if(vis[v]==0&&a[u][v]!=inf&&a[u][v]<d[v]&&d[u]+a[u][v]<d[v]) { d[v]=d[u]+a[u][v]; } } } } int main() { int i,u,v,f,p,j; while(~scanf("%d%d",&n,&m)) { fill(a[0],a[0]+1005*1005,inf); fill(d,d+1005,inf); memset(vis,0,sizeof(vis)); for(i=1;i<=m;i++) { scanf("%d%d%d",&u,&v,&f); a[u][v]=min(a[u][v],f); } d[n]=0; dijkstra();//先求公司到家的最短距离 for(i=1;i<=n;i++) d1[i]=d[i]; fill(d,d+1005,inf); memset(vis,0,sizeof(vis)); int max=0,max1,sum1,t; for(i=1;i<=n;i++) { for(j=i+1;j<=n;j++) { swap(a[i][j],a[j][i]);//反转地图 } } d[n]=0; dijkstra();//再求公司到各个家的距离就是家到公司的最短距离 ,不然超时,直到你退出ACM for(i=1;i<=n;i++) { if(d[i]+d1[i]<inf&&d[i]+d1[i]>max) { max1=i; max=d[i]+d1[i]; } } printf("%d %d\n",max1,max); } }