EOJ-2069 Asteroids

http://acm.cs.ecnu.edu.cn/problem.php?problemid=2069

poj 3041

题意:给出一系列的正整数坐标点,求最少需要几条直线覆盖所有点。

思路:每个点可以由一条垂直的线或一条平行的线覆盖,用匈牙利算法计算出最大匹配,则是需要的直线的数目(意思为若有的点未被匹配到,那一定会被已连接它的某条线覆盖,可以想象成我找了一些横坐标不同的点,然后找每个x方向上的点的纵向是否能够匹配掉一些点,则这些可用垂直线连接)。

若有点x,y 则x->y就有一条通路,每次x匹配y,若y已经被匹配,则看y的顶点是否有增广路径(即有其他的点x',y')

 1 #include<map>
 2 #include<set>
 3 #include<list>
 4 #include<cmath>
 5 #include<ctime>
 6 #include<queue>
 7 #include<stack>
 8 #include<cctype>
 9 #include<cstdio>
10 #include<string>
11 #include<vector>
12 #include<cstdlib>
13 #include<cstring>
14 #include<iostream>
15 #include<algorithm>
16 using namespace std;
17 int v[505];
18 bool mark[505];
19 bool path[505][505];
20 int n;
21 void init(){
22     memset(v,0,sizeof(v));
23     memset(path,0,sizeof(path));
24 }
25 bool find(int x){
26     for(int i=1;i<=n;i++){
27         if(path[x][i]==true && mark[i]==0){
28             mark[i]=true;
29             if(v[i]==0 || find(v[i]) ){
30                 v[i]=x;
31             return true;
32             }
33         }
34     }
35     return false;
36 }
37 int main(){
38     int m;
39     scanf("%d%d",&n,&m);
40         init();
41         while(m--){
42             int a,b;
43             scanf("%d%d",&a,&b);
44             path[a][b]=true;
45         }
46         int ans=0;
47         for(int i=1;i<=n;i++){
48             memset(mark,0,sizeof(mark));
49             if(find(i))ans++;
50         }
51         printf("%d
",ans);
52     return 0;
53 }
View Code
原文地址:https://www.cnblogs.com/KimKyeYu/p/3178660.html