Stay Hungry,Stay Foolish!

C - Path Graph

C - Path Graph

https://atcoder.jp/contests/abc287/tasks/abc287_c

 

思路

判断所有点组成一个链的路径

 

根据每个节点的度来判断:

链路的度: 两边为节点度为1, 中间所有节点度为2.

1 -- 2 -- 2 -- ... -- 2 -- 1

 

同时要防止corner问题出现:

存在两个以上连通子图,但是这些子图不联通。

通过并查集方法判断是否存在多个连通子图。

https://zhuanlan.zhihu.com/p/93647900

CORNER 例如

A -- B

C -- D -- E -- C

 

参考:

https://www.cnblogs.com/Lanly/p/17071525.html

 

Code

https://atcoder.jp/contests/abc287/submissions/38448483

int n, m;
map<int, int> degree;
 
int find(vector<int>& fa, int x)
{
    if(x == fa[x])
        return x;
    else{
        fa[x] = find(fa, fa[x]);  //父节点设为根节点
        return fa[x];         //返回父节点
    }
}
 
int main()
{
    cin >> n >> m;
 
    if (m != n-1){
        cout << "No" << endl;
        return 0;
    }
 
    vector<int> fa(n+1);
    // initialize union set
    for(int i=1; i<=n; i++){
        fa[i] = i;
    }
 
    for(int i=0; i<m; i++){
        int s, t;
        cin >> s >> t;
        
        degree[s]++;
        degree[t]++;
        
        int sfa = find(fa, s);
        int tfa = find(fa, t);
        
        if (sfa != tfa){
            fa[s] = tfa;
        }
    }
 
    map<int, int> cnt;
    for(int i=1; i<=n; i++){
        int deg = degree[i];
        if (deg >= 3 || deg==0){
            cout << "No" << endl;
            return 0;
        }
        
        cnt[deg]++;
    }
 
    int one = cnt[1];
    int two = cnt[2];
 
    if(one != 2){
        cout << "No" << endl;
        return 0;
    }
 
    if (two != n-2){
        cout << "No" << endl;
        return 0;
    }
 
    int blocknum = 0;
    for(int i=1; i<=n; i++){
        if(i == fa[i]){
            blocknum++;
        }
        
        if(blocknum >= 2){
            cout << "No" << endl;
            return 0;
        }
    }
 
    cout << "Yes" << endl;
 
    return 0;
}

 

posted @ 2023-01-29 23:28  lightsong  阅读(34)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel