Ant Trip(歐拉回路+並查集)
阿新 • • 發佈:2018-12-28
Ant Trip
題目描述原題來自:2009 Multi-University Training Contest 12 - Host by FZU
給你無向圖的 N 個點和 M 條邊,保證這 M 條邊都不同且不會存在同一點的自環邊,現在問你至少要幾筆才能所有邊都畫一遍。(一筆畫的時候筆不離開紙)
輸入格式
多組資料,每組資料用空行隔開。 對於每組資料,第一行兩個整數 N,M表示點數和邊數。接下去 M 行每行兩個整數 a,b,表示 a,b 之間有一條邊。
輸出格式
對於每組資料,輸出答案。
樣例
樣例輸入
3 3
1 2
2 3
1 3
4 2
1 2
3 4
樣例輸出
1
2
資料範圍與提示
1≤N≤10^5,0≤M≤2×105,1<=a,b<=N 思路:#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; int n,m,fa[100040],de[100004],sum[100040],num[100004]; void init(){ memset(de,0,sizeof(de)); memset(sum,0,sizeof(sum)); memset(num,0,sizeof(num)); rep(i,1,n) fa[i]=i; } int find(int x){ if(fa[x]==x) return x; else return fa[x]=find(fa[x]); } int main(){ freopen("1.txt","r",stdin) while(~scanf("%d%d",&n,&m)){ int s=0; init(); rep(i,1,m){ int a,b; scanf("%d%d",&a,&b); ++de[a]; ++de[b]; a=find(a); b=find(b); if(a!=b) fa[a]=b; } rep(i,1,n){ if(de[i]&1) sum[find(i)]++; num[find(i)]++; } rep(i,1,n){ if(num[i]==0 || num[i]==1) continue; else if(sum[i]==0) ++s; else s+=(sum[i]/2); } printf("%d\n",s); } return 0; }