3 3 1 2 2 3 1 3 4 2 1 2 3 4
1 2HintNew ~~~ Notice: if there are no road connecting one town ,tony may forget about the town. In sample 1,tony and his friends just form one group,they can start at either town 1,2,or 3. In sample 2,tony and his friends must form two group.
给出一个图,需要几笔能画完题目所描述的所有边。
给出的图是无向图。。。刚开始还以为是二分图的最小路径覆盖。。。无语了。。
用并查集把子图都分开,然后判断每个是否是欧拉回路,如果是那就一笔就ok,如果不是那就需要这个子图里面的奇度数/2笔,然后算出来就好。。
#include <iostream> #include <stdio.h> #include <stdlib.h> #include<string.h> #include<algorithm> #include<math.h> #include<queue> using namespace std; typedef long long ll; const int N=100010; int rd[N],f[N],js[N]; bool vis[N]; vector<int>c; int fa(int x) { if(x!=f[x]) return f[x]=fa(f[x]); return f[x]; } int main() { int m,n; while(~scanf("%d%d",&n,&m)) { c.clear(); for(int i=1; i<=n; i++) f[i]=i; memset(rd,0,sizeof(rd)); while(m--) { int a,b; scanf("%d%d",&a,&b); rd[a]++; rd[b]++; if(fa(a)!=fa(b)) f[fa(a)]=fa(b); } memset(vis,0,sizeof(vis)); memset(js,0,sizeof(js)); for(int i=1; i<=n; i++) { int x=fa(i); if(!vis[x]&&rd[x]) { vis[x]=1; c.push_back(x); } if(rd[i]&1) js[x]++; } int l=c.size(),ans=0; for(int i=0; i<l; i++) if(js[c[i]]==0) ans++; else ans+=js[c[i]]/2; printf("%d\n",ans); } return 0; }