CodeForces 209C Trails and Glades(歐拉回路判斷+並查集計算聯通分量)
阿新 • • 發佈:2019-01-01
題意:判斷能否構成歐拉回路,不能的話輸出最小需要新增多少條邊
題解:並查集處理出聯通分量,輸入時處理出奇度數點個數,結果即為 奇度數點個數/2+不含奇度數點的聯通分量個數,1節點自動算作一個聯通分量 不管是否有邊連線
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <cstdlib> #include <algorithm> #include <cmath> #include <vector> #include <set> #include <list> #include <queue> #include <map> #include <stack> using namespace std; #define L(i) i<<1 #define R(i) i<<1|1 #define INF 0x3f3f3f3f #define pi acos(-1.0) #define eps 1e-3 #define maxn 100010 #define MOD 1000000007 int n,m,ans; int num[1000010],flag[1000010]; int fa[1000010],vis[1000010]; int Find(int x) { return fa[x] = x == fa[x]?x:Find(fa[x]); } void Union(int x,int y) { int fx = Find(x); int fy = Find(y); if(fx != fy) fa[fy] = fx; } int main() { int t,C = 1; while(scanf("%d%d",&n,&m) != EOF) { memset(num,0,sizeof(num)); memset(flag,0,sizeof(flag)); memset(vis,0,sizeof(vis)); for(int i = 1; i <= n; i++) fa[i] = i; int u,v; vis[1] = 1; for(int i = 0; i < m; i++) { scanf("%d%d",&u,&v); if(u != v) { num[u]++; num[v]++; vis[u]++; vis[v]++; Union(u,v); } else vis[u]++; } int ans = 0,k = 0,tong = 0; for(int i = 1; i <= n; i++) if(num[i]&1) flag[Find(i)]++; for(int i = 1; i <= n; i++) if(vis[i] && Find(i)== i) { if(flag[i]) ans += flag[i]; else tong++; k++; } if(k == 1) printf("%d\n",ans/2); else printf("%d\n",ans/2+tong); } return 0; }