标签:define 记录 main 选择 奇数 isod 情况 起点 color
#include <stdio.h> #include<vector> typedef std::vector<int> Vi; #define maxn 300005 //链式存边 int fst[maxn], to[maxn << 1], nxt[maxn << 1], z = 0; void add(int u, int v) { z++; to[z] = v; nxt[z] = fst[u]; fst[u] = z; z++; to[z] = u; nxt[z] = fst[v]; fst[v] = z; } int n, m; int clr[maxn]; Vi rt; int isodd/*是奇数环的标记*/, rat/*涂色矛盾发生的地方,也就是奇数环的起点/终点*/, ended/*完成了环的记录*/; //直接涂色 void dfs(int cid) { int nid; for (int ln = fst[cid]; ln; ln = nxt[ln]) { nid = to[ln]; if (clr[nid] == -1) { clr[nid] = !clr[cid]; dfs(nid); if (ended)return; if (isodd) { rt.push_back(nid); if (cid == rat)//已经回退到环的起点 ended = 1; return; } } else if (clr[nid] == clr[cid]) {//遇到矛盾,开始回退 rat = nid; rt.push_back(nid); isodd = 1; ended = 0; return; } } } int main() { scanf("%d %d", &n, &m); for (int i = 1; i <= n; ++i)clr[i] = -1; int ai, bi; for (int i = 0; i<m; ++i) { scanf("%d%d", &ai, &bi); add(ai, bi); } clr[1] = 1; dfs(1); if (isodd == 0) { printf("0\n"); for (int i = 1; i <= n; ++i)printf("%d ", clr[i]); } else { int sz = rt.size(); //环可能会重复记录起点,去掉就好了 if (rt[sz - 1] == rt[0])sz--; printf("%d\n", sz); for (int i = 0; i<sz; ++i)printf("%d ", rt[i]); } }
nowcoder 203J Graph Coloring I(dfs)
标签:define 记录 main 选择 奇数 isod 情况 起点 color
原文地址:https://www.cnblogs.com/tobyw/p/9741169.html