(欧拉图 并查集 图论) 2922. kotori和旅游

【题目描述】

kotori有一个目标,要旅游遍全日本。

可惜日本太大了,她没有足够的经费。于是kotori计划游览n个地区。她从音乃木坂学院出发,希望把每条线路都走一遍,最后回到音乃木坂学院。

她认为走同一条路是愚蠢的,因此在规划旅游线路的时候不能在同一条路上经历两次。

n个地区之间共有m条线路。kotori想知道她是否能找到一个完美的规划方案?

(注:两个地区之间不保证只有一条线路。一个地区可以被游览多次)

【输入】

第一行有两个整数n,m,代表地区数和线路数(1≤m,n≤100)。

接下来的m行,每行有两个正整数a和b,表示a地区和b地区有一条线路连接。(1≤a,b≤n)

音乃木坂学院记为1号地区。

【输出】

若最终能规划处线路,则输出"Yes"。否则输出"No"。

【样例输入】

3 4

1 2

3 1

1 3

1 2

【样例输出】

Yes

【样例描述】

可选用1→2→1→3→1这样的线路,依次使用第一条、第四条、第二条、第三条线路。

PS:这个是需要校园网才能访问的。http://acm.bistu.edu.cn/acm/submit.jsp?problemID=2922&pageNo=1&pages=0  

和我之前做的题几乎一样。https://www.cnblogs.com/Weixu-Liu/p/10890082.html (一笔画问题)

不过,和这个一笔画问题不同的是,这个题是要回到出发点,emmm,要审题。所以,奇点的个数只能为0。

C++代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 110;
int father[maxn];
int node[maxn];
int n,m;
int Find(int x){
    while(x != father[x]){
        father[x] = father[father[x]];
        x = father[x];
    }
    return x;
}
void Union(int a,int b){
    int ax = Find(a);
    int bx = Find(b);
    if(ax != bx){
        father[ax] = bx;
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++){
        father[i] = i;
    }
    int a,b;
    for(int i = 0; i < m;i++){
        scanf("%d%d",&a,&b);
        Union(a,b);
        node[a]++;
        node[b]++;
    }
    int cnt = 0,cnt1 = 0;
    bool flag1 = true,flag2 = true;
    for(int i = 1; i <= n; i++){
        if(father[i] == i){
            cnt++;
            if(cnt == 2)
                flag1 = false;
        }
        if(node[i] & 1) cnt1++;
    }
    if(cnt1 != 0) flag2 = false;
    if(flag1 && flag2) printf("Yes
");
    else printf("No
");
    return 0;
}
原文地址:https://www.cnblogs.com/Weixu-Liu/p/10890141.html