題目
意思是如果一個圖是一個連通圖而且圖中不含環的話可以視作是一顆樹,給定一個圖,判斷圖可不可以看作一棵樹,如果可以是一顆樹,則找出最深的根並輸出,如果不是則輸出連通分量的個數.
知識點
判斷環
一開始我以爲需要圖中是否存在環,但其實不用,因爲它一定不存在環,看題目的條件,給出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;
}