雕刻时光

just do it……nothing impossible
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

二分图的必须边——pku1486

Posted on 2011-07-20 19:26  huhuuu  阅读(165)  评论(0编辑  收藏  举报
题意是判断二分图的边是否唯一
先最大二分匹配下
枚举 A集合的点所连接的边 删除
在最大二分匹配下看匹配数是否与没删前一样,若不一样,则说明该边是唯一边
View Code
#include<stdio.h>
#include
<string.h>

bool map[59][59];
int mark[59];
int rmark[59];
bool flag[59];
int m,g;

struct data
{
int minx,miny,maxx,maxy;
}node[
59];

struct data1
{
int x,y;
}point[
59];

struct data2
{
char str;
int no;
}temp[
59];

bool dfs(int x)
{
int i;
for(i=1;i<=m;i++)
{
if(map[x][i]==0||flag[i]) continue;

flag[i]
=1;
if(mark[i]==0||dfs(mark[i]))
{
mark[i]
=x;
return 1;
}
}
return 0;
}

int main()
{
int i,k,j;
int count;
int add=0;
while(scanf("%d",&k),k)
{
add
++;
g
=m=k;
memset(map,
0,sizeof(map));
memset(mark,
0,sizeof(mark));
count
=0;

for(i=1;i<=k;i++)
{
scanf(
"%d%d%d%d",&node[i].minx,&node[i].maxx,&node[i].miny,&node[i].maxy);
}
for(i=1;i<=k;i++)
{
scanf(
"%d%d",&point[i].x,&point[i].y);
}

for(i=1;i<=k;i++)
{
for(j=1;j<=k;j++)
{
if(point[j].x>=node[i].minx&&point[j].x<=node[i].maxx)
if(point[j].y>=node[i].miny&&point[j].y<=node[i].maxy)
{
map[i][j]
=1;
}

}
}

for(i=1;i<=g;i++)
{
memset(flag,
0,sizeof(flag));
if(dfs(i)==1) count++;
}
for(i=1;i<=k;i++)//记录mark
{
rmark[i]
=mark[i];
}

int rj;
bool addT=0;
printf(
"Heap %d\n",add);
for(i=1;i<=k;i++)//删除连接的边,看是否最大匹配数是否还为n
{
count
=0;
for(j=1;j<=m;j++)
{
if(rmark[j]==i)
{
rj
=j;
map[i][j]
=0;
break;
}
}


memset(mark,
0,sizeof(mark));
for(j=1;j<=g;j++)
{

memset(flag,
false,sizeof(flag));
if(dfs(j)==1) count++;
}
if(count<k)
{

for(j=1;j<=k;j++)
{
if(rmark[j]==i)
break;
}
if(addT==0)
printf(
"(%c,%d)",'A'-1+i,j);
else
printf(
" (%c,%d)",'A'-1+i,j);
addT
=1;
}

map[i][rj]
=1;
}
if(addT==0)
{
printf(
"none");
}
printf(
"\n\n");
}
}