Linux基础--two

Linux的ACL细部权限

  返回  

【华山论剑题解】

2021/7/20 21:03:05 浏览:

题目描述

话说数年一度的武林盛事“华山论剑”将至,东邪、西毒、南帝、北丐,老顽童等高手云集华山之巅,誓要分出究竟谁是武林至尊……

如此武林盛世,当然求围观。据统计,有n-1位同学想去华山看热闹,他们分别住在编号为1-n(除华山所在地x)的地方,华山编号为x(1<=x<=n)。现在有M(1<=m<=100000)条有向道路,每条路长为ti(1<=ti<=100)。

由于每位同学看完打架后还要回家吃饭,所以要选择最短路径,求这n-1位同学的最短路径(一个来回)中最长的一条的长度。

特别提醒:可能有权值不同的重边。

数据保证每位同学均能到达华山处,并从华山返回。

输入格式

第1行: n,m,x;

第2~m+1行: ai,bi,ti,表示有一条从ai到bi的路,长度为ti.

输出格式

输出仅一行,为最长最短路的长度。

样例

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

数据范围与提示

对于60%的数据,满足 1<=n<=100

对于100%的数据,满足 1<=n<=1000。

分析

思路很简单,都从x开始,SPFA反复跑两遍,两次加起来取max即可,实现起来比较复杂。

90分Floyd算法

#include<bits/stdc++.h>
using namespace std;
int m,n,kk,dis[1001][1001],ans;
int main()
{
	scanf("%d%d%d",&n,&m,&kk);
	memset(dis,0x3f,sizeof(dis));
	for(int i=1;i<=n;i++)
		dis[i][i]=0;
	for(int i=1;i<=m;i++)
	{
		int x,y,z;
		scanf("%d%d%d",&x,&y,&z); 
		dis[x][y]=min(dis[x][y],z);
	}
	for(int k=1;k<=n;k++)
	{
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
			}
		}
	}
	for(int i=1;i<=n;i++)
		ans=max(ans,dis[i][kk]+dis[kk][i]);
	printf("%d",ans);
	return 0;
}

100分SPFA代码

#include<bits/stdc++.h>
using namespace std;
struct edge
{
	int nxt,to,ww;
}w[1000001],w2[1000001];
int head[100001],head2[100001],vis[100001],vis2[100001],d1[100001],d2[100001],tot=0,tot2=0,n,m,xx,yy,zz,kk;
queue<int>q;
void add(int a,int b,int c)
{
	w[++tot].nxt=head[a],w[tot].to=b,head[a]=tot,w[tot].ww=c;
}
void addd(int a,int b,int c)
{
	w2[++tot2].nxt=head2[a],w2[tot2].to=b,head2[a]=tot2,w2[tot].ww=c;
}
void spfa(int u)
{
	while(!q.empty())
		q.pop();
	memset(d1,0x3f,sizeof(d1));
	memset(vis,0,sizeof(vis));
	d1[u]=0;
	vis[u]=1;
	q.push(u);
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		vis[x]=0;
		for(int i=head[x];i;i=w[i].nxt)
		{
			int v=w[i].to;
			if(d1[v]>d1[x]+w[i].ww)
			{
				d1[v]=d1[x]+w[i].ww;
				if(!vis[v])
				{
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
}
void spfaa(int u)
{
	while(!q.empty())
		q.pop();
	memset(d2,0x3f,sizeof(d2));
	memset(vis2,0,sizeof(vis2));
	d2[u]=0; 
	vis2[u]=1;
	q.push(u);
	while(!q.empty())
	{
		int x=q.front();
		q.pop();
		vis2[x]=0;
		for(int i=head2[x];i;i=w2[i].nxt)
		{
			int v=w2[i].to;
			if(d2[v]>d2[x]+w2[i].ww)
			{
				d2[v]=d2[x]+w2[i].ww;
				if(!vis2[v])
				{
					vis2[v]=1;
					q.push(v);
				}
			}
		}
	}
}
int main()
{
	scanf("%d%d%d",&n,&m,&kk);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%d",&xx,&yy,&zz);
		add(xx,yy,zz),addd(yy,xx,zz);
	} 
	spfa(kk);
	spfaa(kk);
	int ans=-0x3f3f3f3f;
	for(int i=1;i<=n;i++)
		ans=max(ans,d2[i]+d1[i]);
	printf("%d",ans);
	return 0;
}

联系我们

如果您对我们的服务有兴趣,请及时和我们联系!

服务热线:18288888888
座机:18288888888
传真:
邮箱:888888@qq.com
地址:郑州市文化路红专路93号