1. 程式人生 > >ZROI17普及23-B星空題解--圖的靈活轉化

ZROI17普及23-B星空題解--圖的靈活轉化

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星空題解--圖的靈活轉化