您的位置:首页 > 其它

poj3020 Antenna Placement 二分匹配之最小路径覆盖

2011-02-09 09:02 281 查看
题目的意思大致就是,一个矩形中,有N个城市,现在这n个城市都要覆盖无线,若放置一个基站,那么它至多可以覆盖相邻的两个城市。
问至少放置多少个基站才能使得所有的城市都覆盖无线?
构图:行扫描所有城市,编号,如果有城市相邻就连一条边,当然如果3和4相邻,首先graph[3][4]=1,当扫描到4时graph[4][3]也连一条边,最后只需要取一半即可.求最大匹配的一半,这样可以得到所有2个相邻城市被一个基站覆盖所需要的基站数。然后再加上独立的那些基站即可。
公式是:N-最大匹配(代表所有可以和相邻城市配对的城市数)+最大匹配/2=N-最大匹配/2;

SourceCode

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
intnx,ny;//X的點數目、Y的點數目
intmx[405],my[405];//X各點的配對對象、Y各點的配對對象
boolvy[405];//紀錄GraphTraversal拜訪過的點
booladj[405][405];//精簡過的adjacencymatrix
intxx,n,m,cc[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
charg[41][11];
//以DFS建立一棵交錯樹
boolDFS(intx)
{
for(inty=0;y<ny;++y)
if(adj[x][y]&&!vy[y])
{
vy[y]=true;

//找到擴充路徑
if(my[y]==-1||DFS(my[y]))
{
mx[x]=y;my[y]=x;
returntrue;
}
}
returnfalse;
}

intbipartite_matching()
{
//全部的點初始化為未匹配點。
memset(mx,-1,sizeof(mx));
memset(my,-1,sizeof(my));

//依序把X中的每一個點作為擴充路徑的端點,
//並嘗試尋找擴充路徑。
intc=0;
for(intx=0;x<nx;++x)
//if(mx[x]==-1)//x為未匹配點,這行可精簡。
{
//開始GraphTraversal
memset(vy,false,sizeof(vy));
if(DFS(x))c++;
}
returnc;
}
voidini()
{
inta,b;
xx=0;
for(inti=0;i<n;i++)
for(intj=0;j<m;j++)
{
if(g[i][j]=='*')
{
xx++;
a=i*m+j;
for(inth=0;h<4;h++)
{
if(i+cc[h][0]>=0&&i+cc[h][0]<n&&j+cc[h][1]>=0&&j+cc[h][1]<m&&g[i+cc[h][0]][j+cc[h][1]]=='*')
{
b=(i+cc[h][0])*m+j+cc[h][1];
adj[a][b]=1;
}
}
}
}
nx=ny=m*n;
}

main()
{
intt,i;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(adj,0,sizeof(adj));
getchar();
for(i=0;i<n;i++)
gets(g[i]);
ini();

printf("%d\n",xx-bipartite_matching()/2);
}
system("pause");
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: