现在的位置: 首页 > 综合 > 正文

HDOJ 3018 – Ant Trip 判断一个无向图由由多少个欧拉(通/回)路构成..注意没有边的点不考虑..

2013年10月14日 ⁄ 综合 ⁄ 共 1158字 ⁄ 字号 评论关闭

              题意:

                      给一个无向图..问由最少可以分解成多少个欧拉(通/回)路

              题解:

                      我是觉得首先要找出每一个联通块..在一个联通块中..两个奇数度的点可以构一条通路...虽然不知道怎么证明..感觉上在一个联通块上最少需要的一笔画为其max(1,其奇数度点数/2)...1是因为若此联通块没有奇数度点..也要画一条欧拉回路把该联通块所有边覆盖...

                      直觉还是挺正确的..也是多画了几个图观察出来的..但是有个trick...有些点是独立的..没有边..处理的时候注意.就无视这些点..而不要把这些点也看成联通块了...

Program:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<time.h>
#include<map>
#include<algorithm>
#define ll long long
#define eps 1e-5
#define oo 1000000007
#define pi acos(-1.0)
#define MAXN 100005
#define MAXM 500005
using namespace std; 
int d[MAXN],father[MAXN],F[MAXN],T[MAXN]; 
bool used[MAXN];
int getfather(int x)
{
       if (father[x]==x) return x;
       return father[x]=getfather(father[x]);   
}
int main()
{        
       int n,m,i,x,y,ans;  
       while (~scanf("%d%d",&n,&m))
       {
               memset(d,0,sizeof(d));
               memset(used,false,sizeof(used));
               for (i=1;i<=n;i++) father[i]=i;
               while (m--)
               {
                       scanf("%d%d",&x,&y);
                       d[x]++,d[y]++;
                       used[x]=used[y]=true;
                       father[getfather(x)]=getfather(y);
               } 
               memset(F,0,sizeof(F)),m=0; 
               for (i=1;i<=n;i++)
                   if (used[i])
                   {
                           if (!F[getfather(i)]) F[father[i]]=++m,T[m]=0;
                           if (d[i]%2) T[F[father[i]]]++; 
                   }
               ans=0;
               for (i=1;i<=m;i++) ans+=max(1,T[i]/2);
               printf("%d\n",ans);
       }
       return 0;
}

抱歉!评论已关闭.