P1640 [SCOI2010]連續攻擊遊戲
阿新 • • 發佈:2018-10-11
|| har i++ break con assert pac std bre
做了這麽長時間的二分圖, 終於發現一個只能用Hungary做的題了.
一眼二分圖, 但是建模非常巧妙. 一開始的想法無非就是把兩個屬性當做二分圖的兩邊, 但是發現這樣似乎不好處理選其中一個的情況.
其實這個應該把屬性放到左邊, 編號放到右邊匹配就ok.
因為編號必須連續的緣故, dinic此處就無能為力了,,,無奈的去現學了一下Hungary,,,
#include <vector> #include <cstdio> #include <cstring> #include <cassert> #include <iostream> #include <algorithm> using namespace std; const int MAXN = 1e6 + 10; inline int read(){ char ch = getchar(); int x = 0; while(!isdigit(ch)) ch = getchar(); while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar(); return x; } int N; int match[MAXN]; bool vis[MAXN]; vector<int> g[(int) 1e4 + 10]; bool dfs(int u) { for(int i = 0; i < (int) g[u].size(); i++) { int &v = g[u][i]; if(!vis[v]) { vis[v] = true; if(!match[v] || dfs(match[v])) return match[v] = u, true; } } return false; } int main(){ cin>>N; for(int i = 1; i <= N; i++) g[read()].push_back(i), g[read()].push_back(i); int ans = 0; for(int i = 1; i <= (int) 1e4; i++) { memset(vis, false, (N + 1) * sizeof(bool)); if(dfs(i)) ++ans; else break; } printf("%d\n", ans); return 0; }
P1640 [SCOI2010]連續攻擊遊戲