洛谷P2185题解

题意理解

虽然背景很多,实际上就是让在一个加权无向联通图中找到最长路(权值为一)。

解法

很明显,因为所有的权值均为一,所以可以理解为没有权值,这样就只用考虑经过路径的多少。

对于固定点出发的图内可以用宽搜和深搜维护最大值,本题解选用用时较少的宽搜。而题目中要求的并不是固定点在图中的最长路,而是图中所有点与点之间的最长路,所以说可以使用循环去一一求解每一个点的最长路,此时在进行比较维护这些数的最大值,即为图中的最长路。

注意事项

本题是要分组的,如果不分组只有 \(20\) 分。

同时,每一组数据都需清空一次图,不然会寄。

Code

#include<stdio.h>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
vector<int>map[1005];//vector建图 
int n,m;
long long bfs(int a){//bfs搜索
	bool check[n+5]={0};//是否有没有走过
	long long dis[n+5]={0};//到每个点的距离
	queue<int>f;
	check[a]=1;
	f.push(a);
	while(f.size()!=0){
		int k=f.front();
		f.pop();
		for(int i=0;i<map[k].size();i++){
			if(check[map[k][i]]==0){
				check[map[k][i]]=1;
				f.push(map[k][i]);
				if(dis[map[k][i]]>p[k]+1||dis[map[k][i]]==0){
					dis[map[k][i]]=p[k]+1;
				}//因为距离是经过边数最少的路径,所以要判一下
			}
		}
	}
	sort(dis+1,dis+1+n);
	return dis[n];//怪异的求最大值
}
int main(){
	while(1!=2){//死循环
		for(int i=1;i<=n;i++){
			map[i].clear();//每一组vector都重置一次
		}
		scanf("%d%d",&n,&m);
		if(n==0&&m==0){
			return 0;	//循环结束也是程序结束的标志:m,n都等于零
		}
		for(int i=1;i<=m;i++){
			int x,y;
			scanf("%d%d",&x,&y);
			map[x].push_back(y);
			map[y].push_back(x); //双向图两边都存一次
		}
		int k1,k2;
		long long Maxn=-1;
		for(int i=1;i<=n;i++){
			Maxn=max(Maxn,bfs(i));//统计最大值
		}
		Maxn*=100;
		printf("%lld\n",Maxn);		
	}

}
posted @ 2022-11-09 23:25  nxhx  阅读(43)  评论(0)    收藏  举报
1 2 3
4