游客 Signup | Login
中文 | En

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

有重边

Time Limit 1 second
Memory Limit 128 MB
Discuss Stats
上一题 下一题