图的遍历
图的遍历
链接:https://ac.nowcoder.com/acm/problem/52275
如果要遍历完整个图的话,就需要整个图联通,就需要这个图中联通块的数量在减1条边;
一个图每个点可以多次遍历的话,只要有奇数环的话就能联通,因此只要判断该图是不是奇数环就行了。用flag来记录这个图是不是奇数环,若果是让flag = 0,否则让flag = 1,最后让结果加上res即可
#include<bits/stdc++.h> using namespace std; const int N = 100010; int n, m, res = 0; vector<int> adj[N]; int flag = 1, st[N]; void dfs(int u) { for(auto x : adj[u]) { if(st[x] == -1) { //没被染色 st[x] = st[u] ^ 1; dfs(x); } else if(st[x] == st[u]) flag = 0; } } int main() { scanf("%d%d", &n, &m); while(m--) { int a, b; scanf("%d%d", &a, &b); adj[a].push_back(b); adj[b].push_back(a); } memset(st, -1, sizeof st); for(int i = 1; i <= n; i++) { if(st[i] == -1) { res++; //联通块个数 st[i] = 0; //进行染色 dfs(i); } } printf("%d", res - 1 + flag); return 0; }
判断该图中是否存在奇数环:
首先对st[]初始化为-1,如果遍历到到该点就将其染色成0,并将其子节点染色成1
这里用异或 0 ^ 1 = 1, 只要相邻的两个点的颜色一样则说明其存在奇数环