奇怪的贪心过了匈牙利,求证明||hack
查看原帖
奇怪的贪心过了匈牙利,求证明||hack
197523
卞云珑楼主2022/4/30 21:40
#include<bits/stdc++.h>
using namespace std;
const int N = 2e3+9;
int a[N],n,m,xx,yy,tot,e;
int vis[N],flag[N],ans;
int temp[N][N],kk;
struct Node
{
	int it,son[N],ru,ru2;
}edge[N];
struct node
{
	int son[N],num;
}T[N];
void check(){for(int i=1;i<=tot;i++){cout<<"!"<<edge[i].it<<" "<<edge[i].ru<<endl;for(int j=1;j<=edge[i].ru2;j++)cout<<edge[i].son[j]<<" ";cout<<"_____________"<<endl;}}
void check2(){for(int i=1;i<=n;i++){if(!T[i].num)continue;cout<<">>>>>"<<endl<<i<<" "<<T[i].num<<endl;for(int j=1;j<=T[i].num;j++){cout<<T[i].son[j]<<" ";}cout<<endl<<"<<<<"<<endl;}}
int main()
{
	cin>>n>>m>>e;
	for(int i=1;i<=e;i++)
	{
		scanf("%d%d",&xx,&yy);yy+=n;
		if(temp[xx][yy])continue;temp[xx][yy]=temp[yy][xx]=1;
		if(!vis[yy])vis[yy]=++tot;
		T[xx].num++;T[xx].son[T[xx].num]=yy;edge[vis[yy]].ru++;edge[vis[yy]].ru2++;edge[vis[yy]].it=yy;edge[vis[yy]].son[edge[vis[yy]].ru]=xx;
	}
	while(kk!=tot)
	{
		int zz=N,i;
		for(int j=1;j<=tot;j++)if(!flag[edge[j].it]&&edge[j].ru<zz)zz=edge[j].ru,i=j;
		int mi=N,mark;
		for(int j=1;j<=edge[i].ru2;j++){int v=edge[i].son[j];if(flag[v])continue;if(T[v].num<mi)mi=T[v].num,mark=v;}flag[edge[i].it]=1,flag[mark]=1,ans++,kk++;
		for(int j=1;j<=T[mark].num;j++){edge[vis[T[mark].son[j]]].ru--;if(!edge[vis[T[mark].son[j]]].ru){if(edge[i].it!=T[mark].son[j]&&!flag[T[mark].son[j]])kk++;flag[T[mark].son[j]]=1;}}
	}
	cout<<ans<<endl;
	return 0;
}

大体思路就是找到所有右部端点中入度最小的点的所有相连的点(左边)中出度最小的点,再用这个点(左边)把它相连的点(右边)的出度更新

2022/4/30 21:40
加载中...