2584 - 聚会
小S想要从某地出发去同学的家中参加一个party,但要有去有回。他想让所用的时间尽量的短。但他又想知道从不同的点出发,来回的最短时间中最长的时间是多少,这个任务就交给了你。
Input
第一行三个正整数n,m,k(n是节点个数,m是有向边的条数,k是参加聚会的地点编号)( 1 ≤ n ≤ 1000 ,1 ≤ m ≤ 100,000)
第二行..m+1行每行3个整数x,y,w 代表从x到y需要花w的时间(1 ≤ w≤ 100)
Output
输出从不同的节点出发的最短时间中最长的时间。
Examples
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
Output
10
Hint
有重边
Solution C++
#include<cstdio> #include<queue> #include<cstring> using namespace std; queue<int> q; int rotb1[1001][1001],rotr1[1001][1001]; int rotb2[1001][1001],rotr2[1001][1001]; long long mi1[1002],mi2[1002]; bool d1[1001],d2[1001]; int main() { //freopen("party.in","r",stdin); //freopen("party.out","w",stdout); int n,m,k,a,b,r; long long maxx=0; scanf("%d%d%d",&n,&m,&k); for (int i=1;i<=m;i++) { scanf("%d%d%d",&b,&a,&r); rotb1[a][++rotb1[a][0]]=b; rotr1[a][++rotr1[a][0]]=r; rotb2[b][++rotb2[b][0]]=a; rotr2[b][++rotr2[b][0]]=r; } memset(mi1,127,sizeof(mi1)); memset(mi2,127,sizeof(mi2)); mi1[k]=mi2[k]=0; q.push(k); while (!q.empty()) { int num=q.front(); q.pop(); d1[num]=false; for (int i=1;i<=rotb1[num][0];i++) { b=rotb1[num][i]; r=rotr1[num][i]; if (mi1[b]>mi1[num]+r) { mi1[b]=mi1[num]+r; if(!d1[b]) { q.push(b); d1[b]=true; } } } } q.push(k); while (!q.empty()) { int num=q.front(); q.pop(); d2[num]=false; for (int i=1;i<=rotb2[num][0];i++) { b=rotb2[num][i]; r=rotr2[num][i]; if (mi2[b]>mi2[num]+r) { mi2[b]=mi2[num]+r; if(!d2[b]) { q.push(b); d2[b]=true; } } } } for (int i=1;i<=n;i++) if(maxx<mi1[i]+mi2[i]&&mi1[i]!=mi1[1001]&&mi2[i]!=mi2[1001]) maxx=mi1[i]+mi2[i]; printf("%lld",maxx); return 0; }
Hint
有重边