个人练习-PAT甲级-1126 Eulerian Path

题目链接https://pintia.cn/problem-sets/994805342720868352/problems/994805349851185152

题目大意:图论。告诉你

  1. 欧拉回路:所有点的degree均为偶数
  2. 欧拉路径:有且仅有两个点的degree为奇数

给出一个无向图的边的信息,输出所有节点的degree,并求该图是欧拉回路还是欧拉路径还是都不满足。

算节点的degree,数degree为奇数的点的个数即可。注意测试点3测试的点是图是是否为连通的。如果图不连通(即有多个连通分量),那么肯定是都不满足的。因此开始时先用DFS数第一个连通分量的点的个数,如果小于N那么就有多个连通分量。

void DFS(int id) {
    known[id] = true;
    cnt++;
    for (int i = 0; i < adj[id].size(); i++) {
        if (!known[adj[id][i]])
            DFS(adj[id][i]);
    }
}

完整代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


using namespace std;


int N, M;
vector<int> adj[501];
vector<int> degree;
vector<bool> known;
int odd;
int cnt;


void DFS(int id) {
    known[id] = true;
    cnt++;
    for (int i = 0; i < adj[id].size(); i++) {
        if (!known[adj[id][i]])
            DFS(adj[id][i]);
    }
}


int Judge() {
    if (cnt < N)
        return 0;

    for (int v = 1; v <= N; v++) {
        if (degree[v] % 2)
            odd++;
    }

    if (odd == 2)
        return 1;
    else if (odd == 0)
        return 2;
    else
        return 0;
}



int main() {
    scanf("%d %d", &N, &M);
    degree.resize(N+1, 0);
    known.resize(N+1, false);
    for (int i = 0; i < M; i++) {
        int v1, v2;
        scanf("%d %d", &v1, &v2);
        adj[v1].push_back(v2);
        adj[v2].push_back(v1);
        degree[v1]++;
        degree[v2]++;
    }

    printf("%d", degree[1]);
    for (int i = 2; i <= N; i++)
        printf(" %d", degree[i]);
    printf("\n");

    DFS(1);

    switch (Judge()) {
        case 0 : printf("Non-Eulerian"); break;
        case 1: printf("Semi-Eulerian"); break;
        default: printf("Eulerian");
    }

    return 0;
}

你可能感兴趣的:(图论)