题目链接:
https://ac.nowcoder.com/acm/problem/20648
题意:
有n个人,m个任务,每个任务有ai和bi两个参数,表示任务在ai手里,ai要交给bi处理。求最多能处理几个任务,在保证任务处理数量最大的情况下,有多少任务是必须要处理的。并且输出必须处理任务的编号。
题解:
二分图匹配,先利用匈牙利算法得到最大匹配数。然后依次删边,判断每条边删除后是否影响最大匹配数,如果影响,则为必须处理的任务,若不影响的话,则不是必须要处理的任务。
AC代码:
#include <bits/stdc++.h>
using namespace std;
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl
const int maxn = 20010;
int u[maxn],v[maxn];
int mp[maxn][maxn] , used[maxn] , match[maxn];
int n , m ,Index;
int ans[maxn];
bool found(int x)
{
for(int i = 1 ; i <= n ; i ++)
{
if(mp[x][i])
{
if(used[i] != Index)
{
used[i] = Index;
if(!match[i] || found(match[i]))
{
match[i] = x;
return 1;
}
}
}
}
return 0;
}
int xiong()
{
memset(match,0,sizeof(match));
int ans = 0 ;
for(int i = 1 ; i <= n ; i++)
{
Index ++;
ans += found(i);
}
return ans;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i = 0 ; i < m ; i++)
{
cin>>u[i]>>v[i];
mp[u[i]][v[i]]++;
}
int ANS = xiong();
int cnt = 0;
for(int i = 0 ; i < m ; i ++)
{
mp[u[i]][v[i]] -- ;
if(xiong() < ANS) ans[cnt++] = i;
mp[u[i]][v[i]] ++ ;
}
cout<<ANS<<" "<<cnt<<"\n";
for(int i = 0 ; i < cnt ; i ++)
cout<<ans[i]+1<<"\n";
}
欢迎评论!