poj 3020 Antenna Placement(二分图的最大匹配)

题目:http://poj.org/problem?id=3020

这个题主要是构图比较难,处理方法是把城市编号然后如果在上下左右四个方向存在城市的话,那么这两个城市就可以组成一条边,构成的图是一个无向图,

DAG图的最小路径覆盖 = 节点数(n)- 最大匹配数;

无向图的最小路径覆盖=节点数(n)-最大匹配数/2;

代码:

View Code
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int map[405][405];
 6 int st[45][15];
 7 int vis[405];
 8 int link[405];
 9 int num;
10 int n,m;
11 int dire[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
12 int find(int x)
13 {
14     int i;
15     for(i=1;i<=num;i++)
16     {
17         if(!vis[i]&&map[x][i])
18         {
19             vis[i]=1;
20             if(link[i]==0||find(link[i]))
21             {
22                 link[i]=x;
23                 return 1;
24             }
25         }
26     }
27     return 0;
28 }
29 int main()
30 {
31     int t,i,j,k,su;
32     char c;
33     scanf("%d",&t);
34     while(t--)
35     {
36         memset(st,0,sizeof(st));
37         memset(map,0,sizeof(map));
38         memset(link,0,sizeof(link));
39         scanf("%d%d",&n,&m);
40         num=0;
41         getchar();
42         for(i=1;i<=n;i++)
43         {
44             for(j=1;j<=m;j++)
45             {
46                 scanf("%c",&c);
47                 if(c=='*')
48                 {
49                     num++;
50                     st[i][j]=num;
51                 }
52             }
53             getchar();
54         }
55         for(i=1;i<=n;i++)
56         {
57             for(j=1;j<=m;j++)
58             {
59                 if(st[i][j]!=0)
60                 {
61                     for(k=0;k<4;k++)
62                     {
63                         if(st[i+dire[k][0]][j+dire[k][1]]!=0)
64                         {
65                             map[st[i][j]][st[i+dire[k][0]][j+dire[k][1]]]=1;
66                         }
67                     }
68                 }
69             }
70         }
71         su=0;
72         for(i=1;i<=num;i++)
73         {
74             memset(vis,0,sizeof(vis));
75             if(find(i))
76             su++;
77         }
78         printf("%d\n",num-(su/2));
79     }
80     return 0;
81 }
原文地址:https://www.cnblogs.com/wanglin2011/p/2819823.html