[luogu2319 HNOI2006] 超級英雄 (匈牙利算法)
阿新 • • 發佈:2018-08-02
sdi 不同的 tor 輸出 是我 desc new eof vector
傳送門
Description
現在電視臺有一種節目叫做超級英雄,大概的流程就是每位選手到臺上回答主持人的幾個問題,然後根據回答問題的多少獲得不同數目的獎品或獎金。主持人問題準備了若幹道題目,只有當選手正確回答一道題後,才能進入下一題,否則就被淘汰。為了增加節目的趣味性並適當降低難度,主持人總提供給選手幾個“錦囊妙計”,比如求助現場觀眾,或者去掉若幹個錯誤答案(選擇題)等等。
這裏,我們把規則稍微改變一下。假設主持人總共有m道題,選手有n種不同的“錦囊妙計”。主持人規定,每道題都可以從兩種“錦囊妙計”中選擇一種,而每種“錦囊妙計”只能用一次。我們又假設一道題使用了它允許的錦囊妙計後,就一定能正確回答,順利進入下一題。現在我來到了節目現場,可是我實在是太笨了,以至於一道題也不會做,每道題只好借助使用“錦囊妙計”來通過。如果我事先就知道了每道題能夠使用哪兩種“錦囊妙計”,那麽你能告訴我怎樣選擇才能通過最多的題數嗎?
Input
輸入的第一行是兩個正整數 n 和 m ( 0 < n < 1001, 0 < m < 1001 )表示總共有 n 種“錦囊妙計”,編號為 0~n?1 ,總共有 m 個問題。
以下的m行,每行兩個數,分別表示第 m 個問題可以使用的“錦囊妙計”的編號。
註意,每種編號的“錦囊妙計”只能使用一次,同一個問題的兩個“錦囊妙計”可能一樣。
Output
輸出的第一行為最多能通過的題數 p ,接下來 p 行,每行為一個整數,第 i 行表示第 i 題使用的“錦囊妙計的編號”。
如果有多種答案,那麽任意輸出一種,本題使用 Special Judge 評判答案。
Sample Input
5 6
3 2
2 0
0 3
0 4
3 2
3 2
Sample Output
4
3
2
0
4
Solution
裸匈牙利算法
Code
//By Menteur_Hxy #include<cstdio> #include<vector> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define F(i,a,b) for(register int i=(a);i<=(b);i++) using namespace std; int read() { int x=0,f=1; char c=getchar(); while(!isdigit(c)) {if(c=='-')f=-f; c=getchar();} while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar(); return x*f; } const int N=1010; int n,m,ans; int vis[N],l[N],r[N]; vector<int> V[N]; bool dfs(int u) { int siz=V[u].size(),v; F(i,0,siz-1) if(!vis[v=V[u][i]]) { vis[v]=1; if(!l[v]||dfs(l[v])) { l[v]=u;r[u]=v; return 1; } } return 0; } int main() { n=read(),m=read(); F(i,1,m) {int x=read(),y=read();V[i].push_back(x),V[i].push_back(y);} F(i,1,m) { memset(vis,0,sizeof(vis)); if(!dfs(i)) break; ans++; } printf("%d\n",ans); F(i,1,ans) printf("%d\n",r[i]); return 0; }
[luogu2319 HNOI2006] 超級英雄 (匈牙利算法)