二分图最大匹配(匈牙利算法) 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\n", 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\n", 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 }

 

你可能感兴趣的:(ide)