poj3041(Asteroids)

题目地址:Asteroids

题目大意:

    给你一个N*N 的格子,在给你星星所在的坐标位置,操作是每次可以消除一整行或一列的星星,问你最小需要多少次操作。

解题思路:

   关键是需要往二分匹配上想。你可以先画图,把星星位置的坐标行和列建图,(1->1,1->3)/(2->2)/(3->2).将所有的边消去就是将所有的星星消去怎么才能最少?这里需要想到连得边最多的点,因为所有的边汇集到一点意思为可以同时消去。所以你只需找到最少的点覆盖所有的边即可,二分图里最小的点覆盖等于最大匹配数。(证明:http://wenku.baidu.com/link?url=_T06jkRwGZphG1B6EDu8WCRnn_5OoIP41WAeasBO72gVinsurM-SDIY2aKY1AeotG8zzW6LsjD49WmYWXfBBlhn0PDlB4vh_ZuHo9h2c-x_

匈牙利算法即可。

代码:

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <sstream>
 4 #include <cstdlib>
 5 #include <cstring>
 6 #include <cstdio>
 7 #include <string>
 8 #include <bitset>
 9 #include <vector>
10 #include <queue>
11 #include <stack>
12 #include <cmath>
13 #include <list>
14 //#include <map>
15 #include <set>
16 using namespace std;
17 /***************************************/
18 #define ll long long
19 #define int64 __int64
20 /***************************************/
21 const int INF = 0x7f7f7f7f;
22 const double eps = 1e-8;
23 const double PIE=acos(-1.0);
24 const int d1x[]= {0,-1,0,1};
25 const int d1y[]= {-1,0,1,0};
26 const int d2x[]= {0,-1,0,1};
27 const int d2y[]= {1,0,-1,0};
28 const int fx[]= {-1,-1,-1,0,0,1,1,1};
29 const int fy[]= {-1,0,1,-1,1,-1,0,1};
30 /***************************************/
31 void openfile()
32 {
33     freopen("data.in","rb",stdin);
34     freopen("data.out","wb",stdout);
35 }
36 /**********************华丽丽的分割线,以上为模板部分*****************/
37 #define MAXN 505
38 int nx,ny;
39 int G[MAXN][MAXN];
40 int cx[MAXN],cy[MAXN];
41 int vis[MAXN];
42 int path(int u)
43 {
44     int v;
45     for(v=0;v<nx;v++)
46         if (G[u][v]&&!vis[v])
47         {
48             vis[v]=-1;
49             if (cy[v]==-1||path(cy[v]))
50             {
51                 cx[u]=v;
52                 cy[v]=u;
53                 return 1;
54             }
55         }
56     return 0;
57 }
58 int MaxMatch()
59 {
60     int cnt=0;
61     memset(cx,-1,sizeof(cx));
62     memset(cy,-1,sizeof(cy));
63     for(int i=0;i<nx;i++)
64     {
65         memset(vis,0,sizeof(vis));
66         cnt+=path(i);
67     }
68     return cnt;
69 }
70 int main()
71 {
72     int m;
73     while(scanf("%d%d",&nx,&m)!=EOF)
74     {
75         int i,j;
76         int x,y;
77         int min=0;
78         memset(G,0,sizeof(G));
79         for(i=0;i<m;i++)
80         {
81             scanf("%d%d",&x,&y);
82             G[x-1][y-1]=1;
83         }
84         min+=MaxMatch();
85         printf("%d
",min);
86     }
87     return 0;
88 }
View Code
屌丝终有逆袭日,*******。
原文地址:https://www.cnblogs.com/ZhaoPengkinghold/p/3842149.html