1. 程式人生 > >【NOIP模擬題】【圖論】2016.11.18 第二題 心 題解

【NOIP模擬題】【圖論】2016.11.18 第二題 心 題解

第二題:心(heart.cpp/c/pas)

背景描述:
不是一切深淵都是滅亡
不是一切滅亡都覆蓋在弱者的頭上
——《這也是一切》 舒婷
有N個透明的盒子, 每個盒子裡面有兩個不同顏色的球, 總共有M種顏色。
Alice和Bob又在玩遊戲, 具體的, Alice會從N個盒子裡面選出若干個, Bob再從Alice選出的盒子裡面選出一些(不能不選), 如果在Bob選出的盒子中, 每個顏色的球都總共出現了偶數次(0次也是偶數次), 那麼Bob勝利, 否則Alice勝利
在Alice和Bob都足夠聰明的情況下, Alice想知道自己在能夠獲勝的前提下, 第一次最多可以選出幾個盒子
輸入格式:
第一行有兩個整數N和M, 意義如題
接下來N行, 第i+1行兩個整數表示第i+1個盒子裡面的兩個球分別是什麼顏色的
輸出格式:
一行一個整數表示Alice最多可以選多少個盒子
樣例輸入:
3 3
1 2
2 3
2 3
樣例輸出:
2
資料規模: 對於30%的資料, N <= 10
對於50%的資料, N <= 20
對於100%的資料, N <= 100000, M <= 2N

我們把每一個顏色當成點,盒子當成線,建一個圖。對於每不合法一個小塊修改為一顆樹。見圖。
這裡寫圖片描述
這是一個合法的圖。
這裡寫圖片描述
這是一個不合法的圖,我們把它修改為上圖。

最後對於每一塊都是點數減一,統計總數。

附程式:

//把顏色當點,盒子當邊,然後對於每一個小塊修改為一棵樹。 
//不是一切深淵都是滅亡
//不是一切滅亡都覆蓋在弱者的頭上
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue> #include<stack> #include<map> #include<set> #include<string> #include<iomanip> #include<ctime> #include<climits> #include<cctype> #include<algorithm> #define clr(a,x) memset(x,a,sizeof(x)) #define ll long long #ifdef WIN32
#define AUTO "%I64d" #else #define AUTO "%lld" #endif using namespace std; const int maxm = 2e5+5; int n,m,a,b,be[maxm],tot,num[maxm],ans; struct Edge { int from,to; int belong; }edge[maxm]; vector<int> g[maxm]; template <class T> inline void read(T &xx) { xx = 0; T flag = 1; char ch = (char)getchar(); while(ch<'0' || ch>'9') { if(ch == '-') flag = -1; ch = (char)getchar(); } while(ch>='0' && ch<='9') { xx = (xx<<1) + (xx<<3) + ch - '0'; ch = (char)getchar(); } xx *= flag; } void dfs(int s) { for(int i = 0; i < g[s].size(); i++) { int v = g[s][i]; if(!be[v]) { be[v] = be[s]; dfs(v); } } } int main() { freopen("heart.in","r",stdin); freopen("heart.out","w",stdout); read(n); read(m); for (int i = 1; i <= n; i++) { read(a); read(b); g[a].push_back(b); g[b].push_back(a); edge[i].to = a; edge[i].from = b; } for (int i = 1; i <= m; i++) { if(!be[i]) be[i] = ++tot; dfs(i); } for (int i = 1; i <= m; i++) num[be[i]]++; for (int i = 1; i <= tot; i++) ans += num[i] - 1; printf("%d",ans); return 0; }