题目链接:HDU 3018 Ant Trip
一笔画问题,问需要多少笔才能把边画完,如果一个连通分量是欧拉回路(所有点的度数都是偶数,对于无向图来说),那么这个连通分量可以一笔画完,如果一个连通分量不是欧拉回路,那么需要的笔画数是这个连通分量中奇数度数点的个数除以2。孤立点不连边,显然不考虑。
#include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <set> #include <iterator> using namespace std; const int MAX_N = 100000 + 100; const int MAX_M = 200000 + 200; int p[MAX_N], dgr[MAX_M], odd[MAX_N]; int n, m; set <int> S; int _find(int x) { return p[x] == x ? x :(p[x] = _find(p[x])); } int main() { int u, v, x, y, _par, _size, res; while(scanf("%d%d", &n, &m) != EOF) { res = 0; memset(dgr, 0, sizeof(dgr)); memset(odd, 0, sizeof(odd)); for(int i = 1; i <= n; i++) p[i] = i; for(int i = 0; i < m; i++) { scanf("%d%d", &x, &y); u = _find(x), v = _find(y); if(u != v) p[u] = v; dgr[x]++, dgr[y]++; } for(int i = 1; i <= n; i++) { if(dgr[i] != 0) { _par = _find(i); if(S.find(_par) == S.end()) S.insert(_par); if(dgr[i] % 2 == 1) odd[_par]++; } } set <int> :: iterator it = S.begin(); for(; it != S.end(); it++) { _par = *it; if(odd[_par]) res += odd[_par] / 2; else res += 1; } printf("%d\n", res); S.clear(); } return 0; }