您的位置:首页 > 其它

poj1486(二分图删边匹配)

2014-05-09 19:22 330 查看
题意:给n(n<=26)张幻灯片,每张上面都有一个数字。给出所有幻灯片的位置和数字的位置,问哪些幻灯片上的数字可以确定。

解法:首先,如果给的合法的话,匈牙利算出来的一定是完全匹配的(也就是说,第一遍二分匹配算出来的一定是完全匹配)。然后再尝试删掉每一条完全匹配中的边,如果删掉后不能完全匹配,则说明这条边是必须的,所以就确定了这个匹配并输出。如果算出的完全匹配中没有一个匹配是必须的,就输出none好了。

代码:

/******************************************************
* author:xiefubao
*******************************************************/
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>
#include <stack>
#include <string.h>
//freopen ("in.txt" , "r" , stdin);
using namespace std;

#define eps 1e-8
const double pi=acos(-1.0);
typedef long long LL;
const int Max=10100;
const int INF=1000000007;

int n;
struct rec
{
int minx,miny,maxx,maxy;
} recs[30];
bool num[30][30];
bool used[30];
int match[30];
int match2[30];
struct point
{
int x,y;
} points[30];
bool OK(const rec& re,const point& p)
{
return (p.x>=re.minx&&p.x<=re.maxx&&p.y>=re.miny&&p.y<=re.maxy);
}
bool dfs(int k)
{
for(int i=0;i<n;i++)
{
if(used[i]||!num[i][k]) continue;
used[i]=1;
if(match[i]==-1||dfs(match[i]))
{
match[i]=k;
return 1;
}
}
return 0;
}
bool dfs2(int k)
{
for(int i=0;i<n;i++)
{
if(used[i]||!num[i][k]) continue;
used[i]=1;
if(match2[i]==-1||dfs(match2[i]))
{
match2[i]=k;
return 1;
}
}
return 0;
}
bool make()
{
int tool=0;
memset(match,-1,sizeof match);
for(int i=0;i<n;i++)
{
memset(used,0,sizeof used);
if(dfs(i)) tool++;
else break;
}
return tool==n;
}
void solve()
{
bool flag=1;
for(int i=0;i<n;i++)
{
num[i][match2[i]]=0;
if(!make())
{
if(!flag) printf(" ");
printf("(%c,%d)",'A'+i,match2[i]+1);
flag=0;
}
else continue;
num[i][match2[i]]=1;
}
if(flag)
printf("none\n");
else printf("\n");
}
int main()
{
int kk=1;
while(scanf("%d",&n)==1)
{
memset(num,0,sizeof num);
if(n==0)
break;
for(int i=0; i<n; i++)
scanf("%d%d%d%d",&recs[i].minx,&recs[i].maxx,&recs[i].miny,&recs[i].maxy);
for(int i=0; i<n; i++)
scanf("%d%d",&points[i].x,&points[i].y);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
num[i][j]=OK(recs[i],points[j]);
memset(match,-1,sizeof match);
int tool=0;
printf("Heap %d\n",kk++);
for(int i=0;i<n;i++)
{
memset(used,0,sizeof used);
if(dfs(i)) tool++;
}
for(int i=0;i<n;i++)
match2[i]=match[i];
solve();
puts("");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: