洛谷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);
}
}

浙公网安备 33010602011771号