二分图最大匹配(匈牙利算法) URAL 1721 Two Sides of the Same Coin
2015-07-18 16:14
447 查看
题目传送门
/* 题意:三种人,statements,testdata,anthing。要求两个人能完成s和t两个工作,且rank相差2 二分图匹配:此题学习建图技巧,两个集和内部一定没有边相连,rank模4小于2和大于等于2的人才能搭配,并且相差正好2, 两个人会的不能一样。以上条件删选出两个集合,不能按照anthing来分。 */ #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <vector> #include <string> #include <cmath> #include <map> using namespace std; const int MAXN = 1e3 + 10; const int INF = 0x3f3f3f3f; struct Setter { char name[22], can[11]; int rk; bool operator < (const Setter &r) const { return rk < r.rk; } }p[MAXN]; int svis[MAXN], vis[MAXN]; int mp[MAXN]; int x[MAXN], y[MAXN]; vector<int> G[MAXN]; int n, un, vn; bool DFS(int u) { for (int i=0; i<G[u].size (); ++i) { int v = G[u][i]; if (!vis[v]) { vis[v] = true; if (y[v] == -1 || DFS (y[v])) { y[v] = u; x[u] = v; return true; } } } return false; } void hungary(void) { sort (p+1, p+1+n); memset (svis, 0, sizeof (svis)); un = 0; for (int i=1; i<=n; ++i) { if (svis[i] != 0 || p[i].rk % 4 > 1) continue; svis[i] = -1; mp[++un] = i; for (int j=1; j<=n; ++j) { if (svis[j] == -1 || p[j].rk % 4 <= 1) continue; if (abs (p[i].rk - p[j].rk) != 2) continue; if (p[i].can[0] == p[j].can[0] && p[i].can[0] != 'a') continue; svis[j] = 1; G[un].push_back (j); } } int res = 0; memset (x, -1, sizeof (x)); memset (y, -1, sizeof (y)); for (int i=1; i<=un; ++i) { memset (vis, false, sizeof (vis)); if (DFS (i)) res++; } printf ("%d\n", res); for (int i=1; i<=un; ++i) { if (x[i] == -1) continue; int id1 = mp[i], id2 = x[i]; if (p[id1].can[0] == 't' || p[id2].can[0] == 's') swap (id1, id2); printf ("%s %s\n", p[id1].name, p[id2].name); } } int main(void) //URAL 1721 Two Sides of the Same Coin { //freopen ("K.in", "r", stdin); scanf ("%d", &n); for (int i=1; i<=n; ++i) { scanf ("%s %s %d", p[i].name, p[i].can, &p[i].rk); } hungary (); return 0; }
相关文章推荐
- 实现JDialog透明背景
- 线段树专题总结
- 常见连接状态
- CSS 收集
- 实时信息处理系统和分时系统从外表看起来很相似,它们有什么本事区别呢?
- day04--面向对象--多态
- sublime text3字体设置方法
- C++实现简单的对象池
- 树的3种表示法
- leetcode | Reverse Nodes in k-Group
- OC学习-继承,便利构造器,初始化方法
- 3Sum
- PRank3
- java 泛型简单使用代码
- 树的3种表示法
- 矩阵及其变换、特征值与特征向量的物理意义
- 黑马程序员——Java基础---面向对象
- The Triangle(简单DP)
- GET和POST有什么区别?只求不再被坑!
- C语言程序设计9