1. 程式人生 > >poj 1486 紙張與數字匹配(二分圖+割邊處理)

poj 1486 紙張與數字匹配(二分圖+割邊處理)

max urn pre con cstring 如果 sha 每次 二分圖

題目來源:http://poj.org/problem?id=1486

題意:

算出所有獨一無二的字母與數字的組合,使二分圖完全匹配

我以為所有點都要獨一無二匹配時輸出匹配方法

題解:

先得到一個完全匹配,然後每次割邊,如果某次割邊後可以完全匹配,則這條邊不是必須的匹配

如果沒有完全匹配或必要的組合數為零時,輸出none

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int maxn=100;
bool ma[maxn][maxn],used[maxn];
int match[maxn];
int ans[maxn];
int cnd=0,n;
struct Node
{
	int a,b,c,d;
}node[maxn];
bool dfs(int x)
{
	if(used[x]==1)return 0;
	else used[x]=1;
     for(int i=1;i<=n;i++)
	 {
		 if(ma[x][i]==0)continue;
		 if(match[i]==0||dfs(match[i]))
		 {
			 match[i]=x;
			 return 1;
		 }
	 }
	 return 0;
}
int hug()
{
	for(int i=1;i<=n;i++)
	{
	   match[i]=0;
	}
	int res=0;
    for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)used[j]=0;
		if(dfs(i))res++;
	}
    return res;
}
int main()
{
    while(scanf("%d",&n)==1)
	{
		if(n==0)break;
		cnd++;
		printf("Heap %d\n",cnd);
                memset(ma,0,sizeof(ma));
		for(int i=1;i<=n;i++)
			scanf("%d %d %d %d",&node[i].a,&node[i].b,&node[i].c,&node[i].d);
		for(int i=1;i<=n;i++)
		{
			int x,y;
			scanf("%d %d",&x,&y);
			for(int j=1;j<=n;j++)
			{
				if(x>=node[j].a&&x<=node[j].b&&y>=node[j].c&&y<=node[j].d)
				{
					ma[i][j]=1;	
				}
			}
		}
                if(hug()==n)
		{
		     for(int i=1;i<=n;i++)
				 ans[i]=match[i];
			 int fla=n;
			 for(int i=1;i<=n;i++)
			 {
				    int k=ans[i];
 					ma[k][i]=0;
					if(hug()==n)
					{
						ans[i]=0;fla--;
					}
 					ma[k][i]=1;
			 }
			 if(fla==0)
			 {
				 cout<<"none"<<endl;
			 }
			 else
			 {
				 int k=0;
				 for(int i=1;i<=n;i++)
				 {
					 if(ans[i]==0)continue;
					 printf("(%c,%d)",‘A‘+i-1,ans[i]);
 					 k++;
					 if(k==fla)cout<<endl;
					 else cout<<" ";

				 }
			 }
		}
		else
		{
                      cout<<"none"<<endl;
		}
        cout<<endl;
	}
	return 0;
}

  

poj 1486 紙張與數字匹配(二分圖+割邊處理)