题意: 给你一个二分图, (可能不连通) 求可能多的子集元素个数;
思路: 直接DFS 给二分图染色就有了, 统计联通块中个数, 去最大值相加即可。
#include<bits/stdc++.h> using namespace std; const int maxn = 20000 + 131; struct Node { int One, Zre; }N[maxn / 2]; vector<int> E[maxn]; bool Vis[maxn]; int Cnt ; void DFS(int e, int k) { for(int i = 0; i < E[e].size(); ++i) { if(Vis[E[e][i]] == false) { //cout << "This is E : " << E[e][i] << endl; Vis[E[e][i]] = true; if(k == 0) N[Cnt].Zre ++; else N[Cnt].One ++; DFS(E[e][i], !k); } } } int Solve() { Cnt = 0; for(int i = 0; i < maxn; ++i) { if(Vis[i] == false && E[i].size()) { Cnt ++; N[Cnt].One = 1; Vis[i] = true; DFS(i, 0); } } /*for(int i = 1; i <= Cnt; ++i) { cout << N[i].Zre << " " << N[i].One << endl; }*/ int Ans = 0; for(int i = 1; i <= Cnt; ++i) Ans += max(N[i].Zre, N[i].One); return Ans; } void INIT() { memset(N,0,sizeof(N)); memset(Vis,0,sizeof(Vis)); for(int i = 0; i < maxn; ++i) E[i].clear(); } int main() { int t, n, u ,v; scanf("%d", &t); for(int kase = 1; kase <= t; ++ kase) { INIT(); scanf("%d", &n); for(int i = 0; i < n; ++i) { scanf("%d %d", &u, &v); E[u].push_back(v); E[v].push_back(u); } int ret = Solve(); printf("Case %d: %d\n", kase, ret); } }
原文:http://www.cnblogs.com/aoxuets/p/4915255.html