SSL1341 Asteroids【二分图匹配】【匈牙利算法】

SSL1341 Asteroids【二分图匹配】【匈牙利算法】_第1张图片
这道题运用的算法和SSL1338 人员分配【二分图匹配】一样,关键是你怎么样建图!
我们可以思考一个问题:怎样让一颗子弹直接把一行或一列打掉呢?
这时我们考虑匹配的性质,当一个点与另一个点匹配,那么这个点就不能再和其他点匹配(暂时)。
会发现,我们可以直接建图,行放在上,列放在下,当枚举到 i i i 点时,产生匹配,
其他所有点都不能与之匹配,相当于把其他边全部断掉(暂时),这就符合了一颗子弹直接把一行或一列打掉的情况。
所以最大匹配就是答案

代码

#include
#include
#include
#include
#include
using namespace std;

int v[1000010],ls[1000010],link[1000010];
int n,k,x,y,tot,ans;

struct node
{
	int y,next;
}a[1000010];
void add(int x,int y)
{
	a[++tot].y=y;
	a[tot].next=ls[x];
	ls[x]=tot;
}
int dfs(int x)
{
	for(int i=ls[x]; i; i=a[i].next)
	 {
	 	int y=a[i].y;
	 	if(v[y]==0)
	 	 {
	 	 	v[y]=1;
	 	 	int fa=link[y];
	 	 	link[y]=x;
	 	 	if(fa==0||dfs(fa))
	 	 	  return 1;
	 	 	link[y]=fa;
	 	 }
	 }
	return 0;
}
int main()
{
    cin>>n>>k;
    for(int i=1; i<=k; i++)
     {
     	scanf("%d%d",&x,&y);
     	add(x,y);
     }
    for(int i=1; i<=n; i++)
     {
     	memset(v,0,sizeof(v));
     	dfs(i);
     }
    for(int i=1; i<=n; i++)  //要循环,不然就会出错
     if(link[i]!=0)
       ans++;
    cout<<ans;
    return 0;
}

你可能感兴趣的:(题解,二分图上的操作,#,匈牙利算法)