pku 3020 Antenna Placement

http://poj.org/problem?id=3020 题目就是一个最小路径覆盖的问题,因为这是一个无向图,所以,最小路径覆盖数 = "*"的总数 - 最大匹配数/2; 如果是一个有向图,则最小路径覆盖数 = "*" 的总数 - 最大匹配数。最大匹配用匈牙利算法就可以了,然后就是建图,因为题目中说了,可以上下左右的覆盖(只要是连着的),所以建图的时候,如果遇到一个 "*" 还要判断一下它的四周是不是也是 "*";

 1 #include<stdio.h>
2 #include<string.h>
3 #include<iostream>
4 using namespace std;
5 #define N 50
6 int map[N*10][N*10],link[N*10],v[N*10],num[N][N];
7 char str[N][N];
8 int move[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
9 int n,m,cnt;
10 int dfs(int x)
11 {
12 int i;
13 for(i=1;i<=cnt;i++)
14 {
15 if(!v[i]&&map[x][i])
16 {
17 v[i]=1;
18 if(link[i]==-1||dfs(link[i]))
19 {
20 link[i]=x;
21 return 1;
22 }
23 }
24 }
25 return 0;
26 }
27 int find()
28 {
29 int i,sum=0;;
30 for(i=1;i<=cnt;i++)
31 {
32 memset(v,0,sizeof(v));
33 if(dfs(i)) sum++;
34 }
35 return sum;
36 }
37 int main()
38 {
39 int i,j,k;
40 int t;
41 cin>>t;
42 while(t--)
43 {
44 cnt=0;
45 cin>>n>>m;
46 for(i=0;i<n;i++)
47 {
48 cin>>str[i];
49 for(j=0;j<m;j++)
50 {
51 if(str[i][j]=='*')
52 num[i][j]=++cnt;
53 }
54 }
55 int x,y;
56 memset(map,0,sizeof(map));
57 /* 建图过程 */
58
59 for(i=0;i<n;i++)
60 {
61 for(j=0;j<m;j++)
62 {
63 for(k=0;k<4;k++)
64 {
65 if(str[i][j]=='*')
66 {
67 x=i+move[k][0];
68 y=j+move[k][1];
69 if(x<n&&x>=0&&y<m&&y>=0&&str[x][y]=='*')
70 {
71 map[num[i][j]][num[x][y]]=1;
72 }
73 }
74 }
75 }
76 }
77 /* 建图过程 */
78
79 memset(link,-1,sizeof(link));
80 int ans=find();
81 cout<<cnt-ans/2<<endl;
82 }
83 return 0;
84 }
原文地址:https://www.cnblogs.com/fxh19911107/p/2398042.html