先通过并查集求集合的个数,如果个数超过1个,输出组成的集合的个数。
如果是连通图,遍历每个结点的层高,通过vector保存最高层的节点编号
//
// main.cpp
// PATA1021
//
// Created by Phoenix on 2018/2/7.
// Copyright © 2018年 Phoenix. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 10010;
int G[maxn][maxn];
struct node {
int data;
vector<int> v;
}node[maxn];
int optvalue = 0, num;
vector<int> ans;
void level(int root) {
bool vis[maxn] = {false};
queue<int> q;
q.push(root);
vis[root] = true;
int lastnode = root, newlastnode;
num = 0;
while(!q.empty()) {
int top = q.front();
q.pop();
//printf("%d ", top);
for(int i = 0; i < node[top].v.size(); i++) {
if(vis[node[top].v[i]] == false) {
q.push(node[top].v[i]);
newlastnode = node[top].v[i];
vis[node[top].v[i]] = true;
}
}
if(top == lastnode){
lastnode = newlastnode;
num++;
}
}
//printf("%d", num);
if(num > optvalue) {
ans.clear();
optvalue = num;
ans.push_back(root);
} else if(num == optvalue) {
ans.push_back(root);
}
//printf("\n");
}
int father[maxn];
void init(){
for(int i = 0; i < maxn; i++){
father[i] = i;
}
}
int findFather(int x) {
int a = x;
while (a != father[a]) {
a = father[a];
}
return a;
}
void Union(int a, int b) {
int faA = findFather(a);
int faB = findFather(b);
if(faA != faB) father[faB] = faA;
}
int main(int argc, const char * argv[]) {
int n;
scanf("%d", &n);
init();
for(int i = 1; i < n; i++) {
int a, b;
scanf("%d %d", &a, &b);
node[a].v.push_back(b);
node[b].v.push_back(a);
Union(a, b);
}
int k = 0;
for(int i = 1; i <= n; i++) {
if(father[i] == i) k++;
}
if(k > 1){
printf("Error: %d components", k);
}else{
for(int i = 1; i <= n; i++) {
level(i);
}
sort(ans.begin(), ans.end());
for(int i = 0; i < ans.size(); i++) {
printf("%d\n", ans[i]);
}
}
return 0;
}
本文介绍了一种使用并查集确定图中连通组件数量的方法,并对最大层级节点进行搜索。首先利用并查集判断图是否完全连通,若非,则输出组件数;若是,则进一步遍历每个节点来找出层高最大的节点。
335

被折叠的 条评论
为什么被折叠?



