CSU-1531 Jewelry Exhibition —— 二分图匹配(最小覆盖点)

 

题目链接:https://vjudge.net/problem/CSU-1531


Input

 

Output

 

Sample Input

2
1 5 3
0.2 1.5
0.3 4.8
0.4 3.5
4 4 8
0.7 0.5
1.7 0.5
2.8 1.5
3.7 0.5
2.2 3.6
2.7 2.7
1.2 2.2
1.2 2.7

Sample Output
1
3

 

 

 

题解:

一开始想用DP做,后来发现不行,因为新加入的点会破坏前面的结果,且不知道前面的状态如何,所以不能用动态规划的思想去解题。 

1.用最少的边去覆盖掉所有的点,顾名思义,可以用二分图的最小覆盖点去做,只是这题的“点”为二分图的边,这题的"边"为二分图的点。

2.把题目的点的x、y坐标看做二分图的点,把题目的点当做二分图的边,其两端是x、y坐标,这样就转化成了用最少的点去覆盖掉所有的边。



代码一(矩阵):

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <vector>
 7 #include <map>
 8 #include <set>
 9 #include <queue>
10 #include <sstream>
11 #include <algorithm>
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define ms(a, b)  memset((a), (b), sizeof(a))
16 #define eps 0.0000001
17 typedef long long LL;
18 const int INF = 2e9;
19 const LL LNF = 9e18;
20 const int mod = 1e9+7;
21 const int maxn = 100+10;
22 
23 int G[maxn][maxn];
24 int vis[maxn], match[maxn];
25 int n,m,k;
26 
27 int find(int u)
28 {
29     for(int i = 0; i<m; i++)
30     {
31         if(G[u][i] && !vis[i] )
32         {
33             vis[i] = 1;
34             if(match[i]==-1 || find(match[i]))
35             {
36                 match[i] = u;
37                 return 1;
38             }
39         }
40     }
41     return 0;
42 }
43 
44 void solve()
45 {
46     double x,y;
47     scanf("%d%d%d",&n,&m,&k);
48 
49     ms(G,0);
50     for(int i = 0; i<k; i++)
51     {
52         scanf("%lf%lf",&x,&y);
53         G[(int)x][(int)y] = 1;
54     }
55 
56     int ans = 0;
57     ms(match,-1);
58     for(int i = 0; i<n; i++)
59     {
60         ms(vis,0);
61         if(find(i))
62             ans++;
63     }
64     printf("%d\n",ans);
65 }
66 
67 int main()
68 {
69     int T;
70     scanf("%d",&T);
71     while(T--){
72         solve();
73     }
74 
75     return 0;
76 }
View Code

 

代码二(vector):

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <vector>
 7 #include <map>
 8 #include <set>
 9 #include <queue>
10 #include <sstream>
11 #include <algorithm>
12 using namespace std;
13 #define pb push_back
14 #define mp make_pair
15 #define ms(a, b)  memset((a), (b), sizeof(a))
16 #define eps 0.0000001
17 typedef long long LL;
18 const int INF = 2e9;
19 const LL LNF = 9e18;
20 const int mod = 1e9+7;
21 const int maxn = 100+10;
22 
23 vector<int> G[maxn];
24 int vis[maxn], match[maxn];
25 int n,m,k;
26 
27 int find(int u)
28 {
29     int Size = G[u].size();
30     for(int i = 0; i<Size; i++)
31     {
32         int v = G[u][i];
33         if(!vis[v] )
34         {
35             vis[v] = 1;
36             if(match[v]==-1 || find(match[v]))
37             {
38                 match[v] = u;
39                 return 1;
40             }
41         }
42     }
43     return 0;
44 }
45 
46 void solve()
47 {
48     double x,y;
49     scanf("%d%d%d",&n,&m,&k);
50 
51     for(int i = 0; i<n; i++)
52         G[i].clear();
53     for(int i = 0; i<k; i++)
54     {
55         scanf("%lf%lf",&x,&y);
56         G[(int)x].pb((int)y);
57     }
58 
59     int ans = 0;
60     ms(match,-1);
61     for(int i = 0; i<n; i++)
62     {
63         ms(vis,0);
64         if(find(i))
65             ans++;
66     }
67     printf("%d\n",ans);
68 }
69 
70 int main()
71 {
72     int T;
73     scanf("%d",&T);
74     while(T--){
75         solve();
76     }
77 
78     return 0;
79 }
View Code

 



 

posted on 2017-04-25 22:29  h_z_cong  阅读(238)  评论(0编辑  收藏  举报

导航