题目
意思是如果一个图是一个连通图而且图中不含环的话可以视作是一颗树,给定一个图,判断图可不可以看作一棵树,如果可以是一颗树,则找出最深的根并输出,如果不是则输出连通分量的个数.
知识点
判断环
一开始我以为需要图中是否存在环,但其实不用,因为它一定不存在环,看题目的条件,给出n个顶点但只给出n-1条边,所以一定构不成一个环,具体的证明我尝试去找了,但是没有找到,以后看到会补.
还有就是在图的边和顶点未知的情况下判断环就是另外一回事了
判断连通及连通分量的个数
判断连通和判断连通分量我已经做过一两次了,主要是利用DFS深度遍历来做
int cnt = 0;
for(int i=1; i<=n; i++) {
if(visited[i]==0) {
dfs(i,1);
if(i==1) {
if(temp.size()!=0)
s = temp[0];
for(int j=0; j<temp.size(); j++) {
result.insert(temp[j]);
}
}
cnt++;
}
找出最长路径的根
这个我一开始没有看懂,后来想到了,因为在图中根是没有顺序的,也就是说,从一个节点开始可以找到最长的一个顶点,那么这个顶点是在最后的,这个是因为代码结构造成的,所以找到之后从后面得往前找一下,有头必有尾.
void dfs(int v,int height) {
if(height>maxheight) {
temp.clear();
temp.push_back(v);
maxheight = height;
} else if(height==maxheight) {
temp.push_back(v);
}
visited[v] = 1;
for(int i=1; i<=n; i++) {
if(visited[i]==0&&graph[v][i]==1) {
dfs(i,height+1);
}
}
}
题目代码
#include <iostream>
#include <vector>
#include <set>
using namespace std;
int n,graph[10010][10010];
int visited[10010];
int maxheight = 0;
vector<int> temp;
set<int> result;
void dfs(int v,int height) {
if(height>maxheight) {
temp.clear();
temp.push_back(v);
maxheight = height;
} else if(height==maxheight) {
temp.push_back(v);
}
visited[v] = 1;
for(int i=1; i<=n; i++) {
if(visited[i]==0&&graph[v][i]==1) {
dfs(i,height+1);
}
}
}
int main() {
cin>>n;
for(int i=1; i<n; i++) {
int v1,v2;
cin>>v1>>v2;
graph[v1][v2] = graph[v2][v1] = 1;
}
int cnt = 0;
int s = -1;
for(int i=1; i<=n; i++) {
if(visited[i]==0) {
dfs(i,1);
if(i==1) {
if(temp.size()!=0)
s = temp[0];
for(int j=0; j<temp.size(); j++) {
result.insert(temp[j]);
}
}
cnt++;
}
}
if(cnt>1) {
cout<<"Error: "<<cnt<< " components";
} else {
fill(visited,visited+10010,0);
temp.clear();
maxheight=0;
dfs(s,1);
for(int i=0; i<temp.size(); i++) {
result.insert(temp[i]);
}
for(auto it=result.begin(); it!=result.end(); it++) {
cout<<*it<<"\n";
}
}
return 0;
}
??正文结束??