1413: StarFarming [最短路]
时间限制: 1 Sec 内存限制: 128 MB提交: 450 解决: 74 统计
题目描述
星农(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
提示
对于样例,
1
来回需要的最短路程是7
:1->2->3->4->1
2
来回需要的最短路程是5
:2->3->4->2
3
来回需要的最短路程是5
:3->4->2->3
所以输出1 7
这个题的需要进行反向存图进行计算,用两次dj算法。
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<iostream>
- #include<cmath>
- #define inf 0x3f3f3f3f
- using namespace std;
- int matrix[1005][1005],matrix1[1005][1005],vis[1005],dis[1005];
- int n,m,x,y,z;
- struct node
- {
- int k,len;
- }s[1005];
- bool cmp(node a,node b)
- {
- if(a.len!=b.len)
- return a.len>b.len;
- return a.k<b.k;
- }
- void dijkstra(int n)//回家的最短路
- {
- memset(vis,0,sizeof(vis));
- memset(dis,inf,sizeof(dis));
- for(int i=1;i<=n;i++)
- dis[i]=matrix[n][i];
- vis[n]=1;
- dis[n]=0;
- int tem,v;
- for(int i=1;i<=n;i++)
- {
- tem=inf;
- for(int j=1;j<=n;j++)
- {
- if(!vis[j]&&dis[j]<tem)
- {
- tem=dis[j];
- v=j;
- }
- }
- vis[v]=1;
- for(int k=1;k<=n;k++)
- {
- if(!vis[k]&&matrix[v][k]<inf)
- dis[k]=min(dis[k],dis[v]+matrix[v][k]);
- }
- }
- }
- void dijkstra1(int n)//求上班的最短路
- {
- memset(vis,0,sizeof(vis));
- memset(dis,inf,sizeof(dis));
- for(int i=1;i<=n;i++)
- dis[i]=matrix1[n][i];
- vis[n]=1;
- dis[n]=0;
- int tem,v;
- for(int i=1;i<=n;i++)
- {
- tem=inf;
- for(int j=1;j<=n;j++)
- {
- if(!vis[j]&&dis[j]<tem)
- {
- tem=dis[j];
- v=j;
- }
- }
- vis[v]=1;
- for(int k=1;k<=n;k++)
- {
- if(!vis[k]&&matrix1[v][k]<inf)
- dis[k]=min(dis[k],dis[v]+matrix1[v][k]);
- }
- }
- }
- int main()
- {
- int n,m;
- while(~scanf("%d %d",&n,&m))
- {
- memset(dis,inf,sizeof(dis));
- memset(matrix,inf,sizeof(matrix));
- memset(matrix1,inf,sizeof(matrix1));
- for(int i=1;i<=m;i++)
- {
- scanf("%d %d %d",&x,&y,&z);
- matrix[x][y]=min(matrix[x][y],z);//防止重边
- matrix1[y][x]=min(matrix1[y][x],z);
- }
- dijkstra(n);
- for(int i=1;i<n;i++)
- s[i].len=dis[i];
- dijkstra1(n);
- for(int i=1;i<n;i++)
- {
- s[i].len+=dis[i];
- s[i].k=i;
- }
- int ans=0,anspos;
- for(int i=1;i<n;i++)
- {
- if(s[i].len<inf){
- ans=s[i].len;
- anspos=i;
- break;//找出第一个存在回路的点
- }
- }
- for(int i=1;i<n;i++){
- if(s[i].len<inf&&s[i].len>ans){
- ans=s[i].len;
- anspos=i;
- }
- }//比较得出最大值和序号
- printf("%d %d\n",anspos,ans);
- }
- return 0;
- }