解题报告
题意:
在h×w的矩阵中,o表示空地,*表示城市,无线设备只能装在城市上,要使城市全都覆盖需要多少设备。每个设备只能覆盖相邻的两个设备。
思路:
感觉是直接的最大匹配,求出两两匹配的最大数,加上没有匹配的城市就是要的答案。
网上看了题解,正解是最小路径覆盖。
最小路径覆盖=|G|-最大匹配数
在一个N*N的有向图中,路径覆盖就是在图中找一些路经,使之覆盖了图中的所有顶点,
且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,
那么恰好可以经过图中的每个顶点一次且仅一次);如果不考虑图中存在回路,那么每每条路径就是一个弱连通子集.
我的最大匹配过的。
#include <iostream> #include <cstring> #include <cstdio> using namespace std; struct node { int v,w,next; } edge[3000]; int cnt,k,head[500],vis[500],pre[500],mmap[100][100],h,w; int dx[]= {-1,0,1,0}; int dy[]= {0,1,0,-1}; void add(int u,int v,int w) { edge[cnt].v=v; edge[cnt].w=w; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].w=w; edge[cnt].next=head[v]; head[v]=cnt++; } int dfs(int x) { for(int i=head[x]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(!vis[v]) { vis[v]=1; if(pre[v]==-1||dfs(pre[v])) { pre[v]=x; return 1; } } } return 0; } int main() { int t,i,j; char str[100]; //freopen("a.in","r",stdin); scanf("%d",&t); while(t--) { memset(head,-1,sizeof(head)); memset(edge,0,sizeof(edge)); memset(pre,-1,sizeof(pre)); memset(mmap,0,sizeof(mmap)); k=0,cnt=0; scanf("%d%d",&h,&w); for(i=1; i<=h; i++) { scanf("%s",str); for(j=0; j<w; j++) { if(str[j]=='*') mmap[i][j+1]=++k; } } for(i=1; i<=h; i++) { for(j=1; j<=w; j++) { if(mmap[i][j]) { for(int l=0; l<4; l++) { if(mmap[i+dx[l]][j+dy[l]]) add(mmap[i][j],mmap[i+dx[l]][j+dy[l]],1); } } } } int ans=0; for(i=1; i<=k; i++) { memset(vis,0,sizeof(vis)); ans+=dfs(i); } printf("%d\n",k-(ans/2)*2+(ans/2)); } }
<pre name="code" class="cpp">官方测试数据: input: 8 40 10 ********** ********** ********** ********** ********** ********** ********** ********** ********** ********** ********** **o******* **oo****** ********** ********** ********** ********** ********** ********** ********** ****oo**** ********** ********** ********** ********** ********** *****ooo** *****o*o** *****ooo** ********** ********** ********** ********** ********** ********** ********** ********** ********** ********** ********** 7 9 ooo**oooo **oo*ooo* o*oo**o** ooooooooo *******oo o*o*oo*oo *******oo 10 1 * * * o * * * * * * 2 1 o o 40 10 o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *ooooooo*o o*o***o*o* *oo*o*oo*o o*o***o*o* *o*ooo*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o o*o*o*o*o* *o*o*o*o*o 37 10 oooooooooo o**ooooooo o*oo**oooo o*****oooo oo**oooooo oooooooooo o**ooooooo o*o**ooooo o******ooo oooooooooo o***oooooo o**ooooooo oooooo***o o********* o***ooo**o oo*oooo**o oo****oo*o oooooooooo oooooooooo oooooooooo oooo****oo ooo**oo**o oooo****oo **oooooooo oooooooooo oooo*ooooo oo****oooo oooo**oooo oooo*ooo*o o*****o**o o*o******o ooooo*oo*o o**oo*oo** oo****oo*o ooo***oooo ooo*****oo oooooooooo 9 10 ********** *oooooooo* *o******o* *o*oooo*o* *o*oooo*o* *o*oooo*o* *o******o* *oooooooo* ********** 2 1 * *
output: 195 17 5 0 193 58 26 1
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 6682 | Accepted: 3319 |
Description
Input
Output
Sample Input
2 7 9 ooo**oooo **oo*ooo* o*oo**o** ooooooooo *******oo o*o*oo*oo *******oo 10 1 * * * o * * * * * *
Sample Output
17 5
POJ训练计划3020_Antenna Placement(二分图/最大匹配),布布扣,bubuko.com
POJ训练计划3020_Antenna Placement(二分图/最大匹配)
原文:http://blog.csdn.net/juncoder/article/details/38611481