1191: [hnoi2006] Superhero herotime limit: 10 sec memory limit: 162 MB
Submit: 1804 solved: 850
[Submit] [Status] Description
There is now a program called superhero on the TV station. The general process is that each contestant answers several questions from the host on the stage, and then receives several prizes or bonuses based on the number of questions answered. The host has prepared several questions. The next question can be entered only when the contestant correctly answers one question. Otherwise, the question will be eliminated. In order to increase the fun of the program and reduce the difficulty as appropriate, the host provides the contestants with a few "Tips", such as asking for help from the audience or removing several wrong answers (multiple choice questions. Here, we will slightly change the rules. Assume that the host has a total of M questions, and the contestants have n Different "Tips ". The host stipulates that each question can be selected from two "Tips", and each "tip" can only be used once. Let's assume that the answer to a question is correct after it is used. Now I came to the Program site, but I was so stupid that I could not do a single question, so I had to use "Tips" for each question. If I know in advance what two tips can be used for each question, can you tell me how to choose the number of questions that can pass the most?
Input
The input file contains two positive integers n and M (0 <n <1001,0 <m <1001), indicating that there are a total of N "tricks", numbered 0 ~ N-1, a total of M problems.
In the following m rows, there are two numbers in each row, indicating the number of the "tip" that can be used for the M-th question, respectively.
Note that each serial number can only be used once. The two "tricks" of the same problem may be the same.
Output
The maximum number of questions that can be passed in the first action.
Sample input5 6
3 2
2 0
0 3
0 4
3 2
3 2 Sample output4hint
I will not go into details about the problems on the Hungarian algorithm online.
The idea of querying sets is that for each question (a, B), the edge in the graph, for a question that cannot be selected (AI, Bi), it must mean ai, bi must already be in a ring, or be in a ring respectively. simply apply and query the set.
I have divided the two methods.
#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define MAXN 1002int fa[MAXN];int get_fa(int x){ if (fa[x]==x)return x; return fa[x]=get_fa(fa[x]);}void init(int n){ int i; for (i=1;i<=n;i++) fa[i]=i;}bool full[MAXN];bool comb(int x,int y){ x=get_fa(x); y=get_fa(y); if (x==y)return false; if (full[x]&&full[y])return false; if (full[x])fa[y]=x;else fa[x]=y; return true;}int main(){ freopen("input.txt","r",stdin); int n,m; scanf("%d%d",&n,&m); int i; init(n); int x,y; for (i=0;i<m;i++) { scanf("%d%d",&x,&y); if (!comb(x,y)) { if (!full[get_fa(x)]) { full[get_fa(x)]=true; }else { printf("%d\n",i); return 0; } } } printf("%d\n",m); return 0;}
And query the Set Method
#include<iostream>#include<cstdio>#include<cstring>using namespace std;#define MAXN 10000int ptr[MAXN][2];int near[MAXN];bool vis[MAXN];bool find(int now){ int i; if (vis[now])return false; vis[now]=true; for (i=0;i<2;i++) { if (near[ptr[now][i]]==-1 || find(near[ptr[now][i]])) { near[ptr[now][i]]=now; return true; } } return false;}int main(){ freopen("input.txt","r",stdin); int n,m; scanf("%d%d",&n,&m); int i; int x,y; memset(near,-1,sizeof(near)); for (i=0;i<m;i++) { scanf("%d%d",&x,&y); ptr[i][0]=x; ptr[i][1]=y; } for (i=0;i<m;i++) { memset(vis,0,sizeof(vis)); if (!find(i))break; } printf("%d\n",i); return 0;}
Hungary Algorithm
Bzoj 1191: [hnoi2006] Superhero hero checklist | Hungarian algorithm