zoukankan      html  css  js  c++  java
  • 二分图最大匹配(匈牙利算法) URAL 1721 Two Sides of the Same Coin

    题目传送门

     1 /*
     2    题意:三种人,statements,testdata,anthing。要求两个人能完成s和t两个工作,且rank相差2
     3    二分图匹配:此题学习建图技巧,两个集和内部一定没有边相连,rank模4小于2和大于等于2的人才能搭配,并且相差正好2,
     4             两个人会的不能一样。以上条件删选出两个集合,不能按照anthing来分。
     5 */
     6 #include <cstdio>
     7 #include <iostream>
     8 #include <algorithm>
     9 #include <cstring>
    10 #include <vector>
    11 #include <string>
    12 #include <cmath>
    13 #include <map>
    14 using namespace std;
    15 
    16 const int MAXN = 1e3 + 10;
    17 const int INF = 0x3f3f3f3f;
    18 struct Setter
    19 {
    20     char name[22], can[11];
    21     int rk;
    22     bool operator < (const Setter &r) const
    23     {
    24         return rk < r.rk;
    25     }
    26 }p[MAXN];
    27 int svis[MAXN], vis[MAXN];
    28 int mp[MAXN];
    29 int x[MAXN], y[MAXN];
    30 vector<int> G[MAXN];
    31 int n, un, vn;
    32 
    33 bool DFS(int u)
    34 {
    35     for (int i=0; i<G[u].size (); ++i)
    36     {
    37         int v = G[u][i];
    38         if (!vis[v])
    39         {
    40             vis[v] = true;
    41             if (y[v] == -1 || DFS (y[v]))
    42             {
    43                 y[v] = u;    x[u] = v;    return true;
    44             }
    45         }
    46     }
    47 
    48     return false;
    49 }
    50 
    51 void hungary(void)
    52 {
    53     sort (p+1, p+1+n);  memset (svis, 0, sizeof (svis));
    54     un = 0;
    55     for (int i=1; i<=n; ++i)
    56     {
    57         if (svis[i] != 0 || p[i].rk % 4 > 1)    continue;
    58         svis[i] = -1;   mp[++un] = i;
    59         for (int j=1; j<=n; ++j)
    60         {
    61             if (svis[j] == -1 || p[j].rk % 4 <= 1)  continue;
    62             if (abs (p[i].rk - p[j].rk) != 2)   continue;
    63             if (p[i].can[0] == p[j].can[0] && p[i].can[0] != 'a')   continue;
    64             svis[j] = 1;    G[un].push_back (j);
    65         }
    66     }
    67 
    68     int res = 0;    memset (x, -1, sizeof (x));    memset (y, -1, sizeof (y));
    69     for (int i=1; i<=un; ++i)
    70     {
    71         memset (vis, false, sizeof (vis));
    72         if (DFS (i))    res++;
    73     }
    74     
    75     printf ("%d
    ", res);
    76     for (int i=1; i<=un; ++i)
    77     {
    78         if (x[i] == -1) continue;
    79         int id1 = mp[i], id2 = x[i];
    80         if (p[id1].can[0] == 't' || p[id2].can[0] == 's')   swap (id1, id2);
    81         printf ("%s %s
    ", p[id1].name, p[id2].name);
    82     }
    83 }
    84 
    85 int main(void)      //URAL 1721 Two Sides of the Same Coin 
    86 {
    87     //freopen ("K.in", "r", stdin);
    88 
    89     scanf ("%d", &n);
    90     for (int i=1; i<=n; ++i)
    91     {
    92         scanf ("%s %s %d", p[i].name, p[i].can, &p[i].rk);
    93     }
    94 
    95     hungary ();
    96     
    97     return 0;
    98 }
    编译人生,运行世界!
  • 相关阅读:
    防御式编程
    Linux磁盘与文件系统管理
    更加抽象
    高质量的子程序
    Linux文件与目录管理
    抽象
    可以工作的类
    Linux的文件权限与目录配置
    条件、循环和其他语句
    软件构建中的设计
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4657119.html
Copyright © 2011-2022 走看看