您的位置:首页 > 其它

PAT 1021. Deepest Root (25) 求根的深度+求连通分量个数

2018-01-03 16:50 579 查看
/*************************
题意:
给一个图,这个图只有n-1条边。
判断这个图是不是树
如果是树,
如果不是树,则输出有几个联通分量
/************************
求解要点和注意点:
用bfs判断深度
复杂度为O(n^2)。
如果发现bfs结束后,遍历的点不足n个
说明一定不是树,故再对其他vis不为1的点做bfs
从而判断有多少个联通分量

************************/

/***********************
笔记:
1.n=10000的O(n^2)是可以不超时的,在1000ms内。
2.注意n=1之类的情况
*********************/

#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<queue>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
using namespace std;
#define M 10010
#define INF 0x7fffffff

vector<int> head[M];
int degree[M];
int vis[M];
int high[M];
int n;
vector<int> ans;
int finddeep(int s){
queue<int> q;
q.push(s);
int nowp,i,flag,nextp,maxh=-1;
memset(vis,0,sizeof(vis));
memset(high,0,sizeof(high));
high[s] = 1;
vis[s]=1;
flag=0;
int count=n;
while(!q.empty()){
nowp = q.front();
q.pop();
count--;
for(i = 0;i < head[nowp].size(); i++){
nextp = head[nowp][i];
if(vis[nextp])
continue;
vis[nextp] = 1;
high[nextp] = high[nowp] + 1;
if(high[nextp] > maxh){
maxh = high[nextp];
}
q.push(nextp);
}
}

if(count==0){
return maxh;
}

int cn = 1;
int j;
for(i=1;i<=n;i++){
if(vis[i]==0){
cn++;
q.push(i);
while(!q.empty()){
nowp = q.front();
q.pop();
for(j=0;j<head[nowp].size();j++){
nextp=head[nowp][j];
if(vis[nextp])
continue;
else
vis[nextp]=1;
q.push(nextp);
}
}
}
}

return (-1)*cn;
}

int main(){
int i,j,s,e;
scanf("%d",&n);
if(n==1){
printf("1\n");
return 0;
}
for(i=0;i<n-1;i++){
scanf("%d%d",&s,&e);
head[s].push_back(e);
head[e].push_back(s);
}
int deep,maxd=-1;
for(i=1;i<=n;i++){
deep = finddeep(i);
if(deep<0){
printf("Error: %d components\n",(-1)*deep);
return 0;
}
else if(deep > maxd){
ans.clear();
ans.push_back(i);
maxd=deep;
}
else if(deep == maxd){
ans.push_back(i);
}
}

sort(ans.begin(),ans.end());
for(i=0;i<ans.size();i++)
printf("%d\n",ans[i]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: