POJ 1486 Sorting Slides 二分匹配变形 完全匹配

来源:互联网 发布:酒店网络设计 编辑:程序博客网 时间:2024/06/07 16:04
http://poj.org/problem?id=1486
题意:给你xy平面内的n个矩形,和n个数字,每个矩形上都有一个数字,要求输出能确定的矩形和数字的对应关系;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <algorithm>
#include <set>
using namespace std;
typedef long long ll;
typedef unsigned long long Ull;
#define MM(a,b) memset(a,b,sizeof(a));
const double eps = 1e-10;
const int inf = 0x3f3f3f3f;
const double pi=acos(-1);
const int mod=100000000;
int max(int a,int b)
{return a>b?a:b;};
int min(int a,int b)
{return a<b?a:b;};
int match[20005],path[20005];
struct rec{
int l,r,u,d;
}ne[10005];
int n,used[10005];
int G[1010][1010];//数组大小神坑,看了好几遍也看不出来题目的数据范围

bool dfs(int u)
{
used[u]=1;
for(int v=n;v<=2*n-1;v++)
if(G[u][v])
{
int w=match[v];
if(w<0||!used[w]&&dfs(w))
{
match[u]=v;
match[v]=u;
return true;
}
}
return false;
}

int solve()
{
int res=0;
memset(match,-1,sizeof(match));
for(int i=0;i<n;i++)
if(match[i]<0)
{
MM(used,0);
if(dfs(i)) res++;
}
return res;
}

void add_edge(int u,int v)
{
G[u][v]=1;
G[v][u]=1;
}

int x[10005],y[10005];
int main()
{
int cnt=0;
while(~scanf("%d",&n)&&n)
{
MM(G,0);
for(int i=0;i<n;i++)
scanf("%d %d %d %d",&ne[i].l,&ne[i].r,&ne[i].d,&ne[i].u);
for(int i=0;i<n;i++)
scanf("%d %d",&x[i],&y[i]);

for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(x[j]>ne[i].l&&x[j]<ne[i].r&&y[j]>ne[i].d&&y[j]<ne[i].u)
add_edge(i,j+n);

printf("Heap %d\n",++cnt);
int ans0=solve();

for(int i=0;i<n;i++)
path[i]=match[i];
int flag=0;
for(int u=0;u<n;u++)
{
int v=path[u];
G[u][v]=G[v][u]=0;//测试方案是否唯一
int ans=solve();
if(ans!=ans0)
{
printf("(%c,%d) ",u+'A',v-n+1);
flag=1;
}
G[u][v]=G[v][u]=1;
}
if(flag) printf("\n");
else printf("none\n");
printf("\n");
}
return 0;
}
分析:刚开始以为就是一道二分匹配的水题,后来发现不对了,,因为求出来的最大匹配数永远会是矩形的个数的,
才注意到题目说的是能确定的。。。;
解决办法:先最大匹配跑一跑,然后对左边每个点,删除先前跑出来的匹配的这条边(即看是否还有新的分配方案),
若还能成为完美匹配(即形成一个新的分配方案),说明左边这个点对应的右边的点不唯一,即这个点无法确定。
原创粉丝点击