1、本题是一道二分图最大匹配的变形,学了一下增广路算法,还是挺好写的。
2、由于答题是按顺序的,一旦答错就不能再答,所以依题目顺序寻找,尽量找到最大匹配。
3、第一题(点1)是未盖点,从点1开始寻找增广路,直到找到另一个未盖点为止(此时算作找到一条增广路),然后在dfs里顺便更新一下匹配边。
4、接着找第二题(点2)的增广路,注意一旦找过的不用再找,因此找过的结点要用vis数组标记,当然了,每一题都要将vis清零,因为每次都要找一个新的匹配。
5、依次类推,直到找不到增广路为止,输出当前答过的题数。
#include<cstdio>#include<cstring>
using namespace std;
const int V=1010;
int e[V][2],left[V],n,m;
bool vis[V];
bool dfs(int x){
if(vis[x]) return 0;
vis[x]=1;
for(int i=0;i<2;i++){
int t=e[x][i];
if(left[t]==-1||dfs(left[t])){
left[t]=x;
return 1;
}
}
return 0;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)
scanf("%d%d\n",&e[i][0],&e[i][1]);
for(int i=0;i<n;i++) left[i]=-1;
int ans;
for(ans=0;ans<m;ans++){
memset(vis,0,sizeof(vis));
if(!dfs(ans)) break;
}
printf("%d\n",ans);
return 0;
}