bzoj 1191超級英雄Hero|匈牙利演算法|水題
阿新 • • 發佈:2019-02-09
Description
現在電視臺有一種節目叫做超級英雄,大概的流程就是每位選手到臺上回答主持人的幾個問題,然後根據回答問題的多少獲得不同數目的獎品或獎金。主持人問題準備了若干道題目,只有當選手正確回答一道題後,才能進入下一題,否則就被淘汰。為了增加節目的趣味性並適當降低難度,主持人總提供給選手幾個“錦囊妙計”,比如求助現場觀眾,或者去掉若干個錯誤答案(選擇題)等等。 這裡,我們把規則稍微改變一下。假設主持人總共有m道題,選手有n種不同的“錦囊妙計”。主持人規定,每道題都可以從兩種“錦囊妙計”中選擇一種,而每種“錦囊妙計”只能用一次。我們又假設一道題使用了它允許的錦囊妙計後,就一定能正確回答,順利進入下一題。現在我來到了節目現場,可是我實在是太笨了,以至於一道題也不會做,每道題只好藉助使用“錦囊妙計”來通過。如果我事先就知道了每道題能夠使用哪兩種“錦囊妙計”,那麼你能告訴我怎樣選擇才能通過最多的題數嗎?
Input
輸入檔案的一行是兩個正整數n和m(0 < n <1001,0 < m < 1001)表示總共有n中“錦囊妙計”,編號為0~n-1,總共有m個問題。
以下的m行,每行兩個數,分別表示第m個問題可以使用的“錦囊妙計”的編號。
注意,每種編號的“錦囊妙計”只能使用一次,同一個問題的兩個“錦囊妙計”可能一樣。
Output
第一行為最多能通過的題數p
Sample Input
5 6
3 2
2 0
0 3
0 4
3 2
3 2
Sample Output
4
Hint
Source
HNOI2006
題解
裸的二分圖匹配……然而本蒟看混m和n依然WA了兩次而且還以為演算法寫錯了……
匈牙利演算法
程式碼
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=1005;
struct data{int to,next;}e[maxn*2];
int head[maxn],cnt,qua[maxn],n,m;
bool used[maxn];
inline void insert(int u,int v){cnt++;e[cnt].to=v;e[cnt].next=head[u];head[u]=cnt;}
bool dfs(int s)
{
for(int i=head[s];i;i=e[i].next)
if(!used[e[i].to])
{
used[e[i].to]=1;
if(!qua[e[i].to]||dfs(qua[e[i].to]))
{
qua[e[i].to]=s;
return 1;
}
}
return 0;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(x==y)insert(i,x);
else insert(i,x),insert(i,y);
}
int ans=0;
for(int i=1;i<=m;i++)
{
memset(used,0,sizeof(used));
if(dfs(i))ans++;
else break;
}
printf("%d\n",ans);
return 0;
}
——既然選擇了遠方,便只顧風雨兼程