• 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
    ",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
    ",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



  • 相关阅读:
    多线程
    多线程
    多线程
    多线程
    Java 基础
    异常
    多线程
    多线程
    多线程
    幂等性
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/7538714.html
Copyright © 2020-2023  润新知