您的位置:首页 > 其它

HPU1413 StarFarming(最短路,SPFA,河南省多校连萌(三))

2017-08-11 18:18 726 查看
题目:


1413: StarFarming [最短路]

时间限制: 1 Sec 内存限制:
128 MB

提交: 303 解决:
35 统计


题目描述

星农(StarFarming)公司计划要给员工发路费津贴,发放的规则是这样的:
1
n-1
代表各个员工家的序号,
n
代表公司。路费津贴只发给上班的最短路与回家的最短路的总路程最长的人。该市的路建造的有些奇怪,修路只修单行道,即只允许往某一个方向通行。
现在给你城市的有向图的地图,TLG请你帮忙计算谁能得到津贴,以及他上班和回家的总路程是多少。


输入

有多组测试数据。
每组第一行输入两个整数
N
M
。表示点的个数,与单行道的数量(可能有重复)
接下来
m
行,每行输入三个整数
x
,
y
,
z
。表示从
x
y
城市有一条单行道,距离为
z

题目保证至少一人存在来回的路径。不存在的不发津贴(班都没法好好上还想要钱?!)

1≤N≤10001≤N≤1000

1≤M≤1000001≤M≤100000

1≤x,y≤N1≤x,y≤N

1≤z≤2001≤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



来源

WYG

提交讨论

思路:

中文题意,就不说了,先反向建边跑一遍SPFA算出各个点到n的最短路,然后在正向建边,算出n到各个点的最短路,求最大值就可以,主要是封装了一个SPFA类,来试试

代码:

#include <cstdio>
#include <cstring>
#include <cctype>
#include <string>
#include <set>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define mod 1000007
#define N 101000
#define M 12357
#define ll long long
using namespace std;
int n,m,a,b,c;
struct SPFA
{
void init()
{
mem(first,-1);
mem(vis,0);
mem(dis,0);
len=1;
}
int first
,len,vis
,dis
;
struct node
{
int u,v,w,next;
} G
;
void add_edge(int u,int v,int w)
{
G[len].v=v,G[len].w=w;
G[len].next=first[u];
first[u]=len++;
}
void spfa(int st)
{
for(int i=1; i<=n; i++)
{
dis[i]=inf;
vis[i]=0;
}
dis[st]=0;
vis[st]=1;
queue<int>q;
q.push(st);
while(!q.empty())
{
st=q.front();
q.pop();
vis[st]=0;
for(int i=first[st]; i!=-1; i=G[i].next)
{
int v=G[i].v,w=G[i].w;
if(dis[v]>dis[st]+w)
{
dis[v]=dis[st]+w;
if(!vis[v])
{
vis[v]=1;
q.push(v);
}
}
}
}
}
} s1,s2;
int main()
{
while(~scanf("%d%d",&n,&m))
{
s1.init();
s2.init();
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&a,&b,&c);
s1.add_edge(b,a,c);
s2.add_edge(a,b,c);
}
s1.spfa(n);
s2.spfa(n);
int maxx=0,k=0;
for(int i=1; i<=n-1; i++)
{
if(s1.dis[i]!=inf&&s2.dis[i]!=inf)
{
int sum=s1.dis[i]+s2.dis[i];
if(sum>maxx)
{
maxx=sum;
k=i;
}
}
}
printf("%d %d\n",k,s1.dis[k]+s2.dis[k]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: