题目链接:Click here~~
题意:
无向图中,不算孤立点,问最少几笔才能画完。
解题思路:
结论:对于每个连通分量,如果不存在奇度点,那么它需要 1 笔。如果存在,那么它需要 奇度点/2 笔。
#include <map> #include <stdio.h> #include <string.h> #include <algorithm> using namespace std; namespace UFset { const int N = 1e5 + 5; int pre[N]; void init(){ memset(pre,-1,sizeof(pre)); } int root(int x){ return pre[x] == -1 ? x : pre[x] = root(pre[x]); } bool gather(int a,int b){ int r1 = root(a); int r2 = root(b); if(r1 == r2) return false; else pre[r1] = r2; return true; } } using namespace UFset; int deg[N]; bool EulerTour(int n) //un-direct { int rt = root(1); for(int i=1;i<=n;i++) if(root(i) != rt || deg[i] & 1) return false; return true; } int EulerTourCnt(int n) { map<int,int> M; for(int i=1;i<=n;i++) { if(deg[i] == 0) continue; int rt = root(i); if(!M.count(rt)) M[rt] = 0; if(deg[i] & 1) M[rt]++; } int cnt = 0; for(map<int,int>::iterator it=M.begin();it!=M.end();it++) cnt += (*it).second ? (*it).second/2 : 1; return cnt; } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { init(); memset(deg,0,sizeof(deg)); for(int i=0;i<m;i++) { int u,v; scanf("%d%d",&u,&v); ++deg[u] , ++deg[v]; gather(u,v); } printf("%d\n",EulerTourCnt(n)); } return 0; }