ZROI17普及23-B星空題解--圖的靈活轉化
阿新 • • 發佈:2018-08-11
ctype 一道 cstring ffffff roi int 題目 ret pre
題目鏈接
版權原因不予提供
分析
這題思路很妙啊,雖然已經算半個套路題(因為我太菜了)
將框視為點,若一個球能放在\(x\)或\(y\)框,則\(x,y\)連一條無向邊。有一條非常顯然的性質是:在聯通塊中,若有奇數條邊,則經過一定能調整使得最少有一個答案貢獻,若有奇數條邊,則最少對答案沒有貢獻
這個性質其實非常好想,但我想了挺久找不出合適的話來解釋,標程用圖來解釋就比較直觀更好處理
於是我們只要模擬上述過程就好了,一道看似與圖無關的題用圖就迎刃而解
代碼
#include <cstdio> #include <cstring> #include <cstring> #include <cctype> #include <algorithm> #include <queue> #include <vector> #include <cmath> #include <iostream> #define ll long long #define ri register int #define ull unsigned long long using namespace std; template <class T>inline void read(T &x){ x=0;int ne=0;char c; while(!isdigit(c=getchar()))ne=c==‘-‘; x=c-48; while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48; x=ne?-x:x;return ; } const int maxn=200005; const int inf=0x7fffffff; int n,m; int fa[maxn],num[maxn]; int get(int x){return (x==fa[x])?fa[x]:(fa[x]=get(fa[x]));} int main(){ int x,y; srand(19260817);//悶聲發大財 預祝長者大壽 Long Live Jiang !!! read(n),read(m); for(ri i=1;i<=m;i++)fa[i]=i; for(ri i=1;i<=n;i++){ read(x),read(y); x=get(x),y=get(y); if(x==y)num[x]++; else { fa[x]=y; num[y]=num[y]+num[x]+1; } } ll ans=0; for(ri i=1;i<=m;i++){ if(i==fa[i])ans+=(num[i]%2); } printf("%lld\n",ans); return 0; }
ZROI17普及23-B星空題解--圖的靈活轉化