1. 程式人生 > >HDU 3018 Ant Trip (並查集求連通塊數+歐拉回路)

HDU 3018 Ant Trip (並查集求連通塊數+歐拉回路)

http 道路 遇到 連通塊 ems ble define ant trip 註意

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3018

題目大意:有n個點,m條邊,人們希望走完所有的路,且每條道路只能走一遍。至少要將人們分成幾組。

解題思路:先用並查集求出所有的連通塊,然後判斷每個連通塊內點的度數,如果有奇數點則需要的組數ans+=奇數點/2;反之,所需組數ans+=1。註意:如果遇到孤立點即度數為0的點則不用算進去,因為沒有跟他相連的邊。

代碼:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<queue>
 5
#define CLR(arr,val) memset(arr,val,sizeof(arr)) 6 using namespace std; 7 const int N=1e6+5; 8 9 int n,m; 10 int deg[N],root[N],num[N];//num[i]記錄集合i內的奇數點個數 11 12 void init(){ 13 CLR(deg,0); 14 CLR(num,0); 15 for(int i=1;i<=n;i++) 16 root[i]=i; 17 } 18 19 int
find(int x){ 20 return root[x]==x?x:root[x]=find(root[x]); 21 } 22 23 int main(){ 24 while(~scanf("%d%d",&n,&m)){ 25 init(); 26 for(int i=1;i<=m;i++){ 27 int u,v,x,y; 28 scanf("%d%d",&u,&v); 29 x=find(u); 30 y=find(v);
31 deg[u]++; 32 deg[v]++; 33 if(x!=y) 34 root[x]=y; 35 } 36 for(int i=1;i<=n;i++){ 37 if(deg[i]%2==1) 38 num[find(i)]++; 39 } 40 int ans=0; 41 for(int i=1;i<=n;i++){ 42 if(deg[i]==0) 43 continue; 44 if(find(i)==i){ 45 if(num[i]==0) 46 ans++; 47 else 48 ans+=num[i]/2; 49 } 50 } 51 printf("%d\n",ans); 52 } 53 return 0; 54 }

HDU 3018 Ant Trip (並查集求連通塊數+歐拉回路)