1021 Deepest Root

题目

题目链接

意思是如果一个图是一个连通图而且图中不含环的话可以视作是一颗树,给定一个图,判断图可不可以看作一棵树,如果可以是一颗树,则找出最深的根并输出,如果不是则输出连通分量的个数.

知识点

判断环

一开始我以为需要图中是否存在环,但其实不用,因为它一定不存在环,看题目的条件,给出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;
}

??正文结束??
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值