jzoj4671-World Tour【图论,bfs】

正题

luogu题目链接:https://www.luogu.org/problemnew/show/CF666B


题目大意

求4个点,使得这4个点按顺序最短路到达的长度最远。


解题思路

b f s bfs bfs求出每个点之间的最短路,然后对于每个点求出最远点,次远点,反最远点和反次远点。
之后枚举中间两个点,然后如果最远的相同就一个用次远,否则都用最远。


c o d e code code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int N=5100,M=10100;
struct edge{
	int to,next;
}a[M];
int n,tot,m,f[N][N],maxs,ls[N],mark[4];
int ffar[N],ffar2[N],far[N],far2[N];
queue<int> q;
void adde(int x,int y)
{
	a[++tot].to=y;
	a[tot].next=ls[x];
	ls[x]=tot;
}
void bfs(int s)
{
	q.push(s);f[s][s]=0;
	while(!q.empty())
	{
		int x=q.front();q.pop();
		for(int i=ls[x];i;i=a[i].next)
		{
			int y=a[i].to;
			if(f[s][y]<0)
			{
				f[s][y]=f[s][x]+1;
				q.push(y);
			}
		}
	}
}
int main()
{
	memset(f,0xcf,sizeof(f));
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		adde(x,y);
	}
	for(int i=1;i<=n;i++)
	  bfs(i);
	for(int i=1;i<=n;i++)
	{
	    for(int j=1;j<=n;j++)
	    {
	    	if(i==j) continue;
	    	if(f[i][j]>f[i][far[i]]){
	    		far2[i]=far[i];
	    		far[i]=j;
	    	}
	    	else if(f[i][j]>f[i][far2[i]])
	    	  far2[i]=j;
	    }
	}
	for(int i=1;i<=n;i++)
	{
	    for(int j=1;j<=n;j++)
	    {
	    	if(i==j) continue;
	    	if(f[j][i]>f[ffar[i]][i]){
	    		ffar2[i]=ffar[i];
	    		ffar[i]=j;
	    	}
	    	else if(f[j][i]>f[ffar2[i]][i])
	    	  ffar2[i]=j;
	    }
	}
	for(int i=1;i<=n;i++)
	  for(int j=1;j<=n;j++)
	    if(i!=j)
	    {
	    	if(!ffar[i]||!far[j]||ffar[i]==j||far[j]==i) continue;
	  	  	if(ffar[i]==far[j])
	  	  	{
	  	  	  	if(f[ffar2[i]][i]+f[j][far[j]]+f[i][j]>maxs&&ffar2[i])
	  	  	  	{
	  	  	  	 	maxs=f[ffar2[i]][i]+f[j][far[j]]+f[i][j];
	  	  	  	  	mark[0]=ffar2[i];mark[1]=i;
	  	  	  	  	mark[2]=j;mark[3]=far[j];
	  	  	 	}
	  		  	if(f[ffar[i]][i]+f[j][far2[j]]+f[i][j]>maxs&&far2[j])
	  	  	  	{
	  	  	  	  	maxs=f[ffar[i]][i]+f[j][far2[j]]+f[i][j];
	  	  	  	  	mark[0]=ffar[i];mark[1]=i;
	  	  	  	  	mark[2]=j;mark[3]=far2[j];
	  	  		}
	  	  	}
	  	  	else
	  	    	if(f[ffar[i]][i]+f[j][far[j]]+f[i][j]>maxs)
	  	  		{
	  	  	  	  	maxs=f[ffar[i]][i]+f[j][far[j]]+f[i][j];
	  	  	  	  	mark[0]=ffar[i];mark[1]=i;
	  	  	  	  	mark[2]=j;mark[3]=far[j];
	  	  		}
	  	}
	printf("%d %d %d %d",mark[0],mark[1],mark[2],mark[3]);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值