题目链接: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;
}