FZU 2194 星系碰撞(二分图匹配)
来源:互联网 发布:js div显示隐藏 编辑:程序博客网 时间:2024/04/30 09:31
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2194
思路:对于所有点将与其距离 <= 5 的点连边,然后跑二分图匹配,最后算出最大独立集,这题数据量比较大,用的是Hopcroft-Carp算法,复杂度O(sqrt(n) * E),另外使用map时要使用内置的pair类型和find函数,否则会T。。。
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <utility>#include <cmath>#include <queue>#include <set>#include <map>#include <climits>#include <functional>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int MAXN = 50010;const int INF = INT_MAX - 1;vector <int> G[MAXN];int uN;int Mx[MAXN], My[MAXN];int dx[MAXN], dy[MAXN];int dis;bool used[MAXN];struct node{ int x, y;} a[MAXN];typedef pair <int, int> P;bool SearchP(){ queue <int> Q; dis = INF; memset(dx, -1, sizeof(dx)); memset(dy, -1, sizeof(dy)); for (int i = 0 ; i < uN; i++) if (Mx[i] == -1) { Q.push(i); dx[i] = 0; } while (!Q.empty()) { int u = Q.front(); Q.pop(); if (dx[u] > dis)break; int sz = G[u].size(); for (int i = 0; i < sz; i++) { int v = G[u][i]; if (dy[v] == -1) { dy[v] = dx[u] + 1; if (My[v] == -1)dis = dy[v]; else { dx[My[v]] = dy[v] + 1; Q.push(My[v]); } } } } return dis != INF;}bool DFS(int u){ int sz = G[u].size(); for (int i = 0; i < sz; i++) { int v = G[u][i]; if (!used[v] && dy[v] == dx[u] + 1) { used[v] = true; if (My[v] != -1 && dy[v] == dis)continue; if (My[v] == -1 || DFS(My[v])) { My[v] = u; Mx[u] = v; return true; } } } return false;}int MaxMatch(){ int res = 0; memset(Mx, -1, sizeof(Mx)); memset(My, -1, sizeof(My)); while (SearchP()) { memset(used, false, sizeof(used)); for (int i = 0; i < uN; i++) if (Mx[i] == -1 && DFS(i)) res++; } return res;}map <P, int> ma;void init(int n){ ma.clear(); for (int i = 0; i <= n; i++) G[i].clear();}int main(){ int n; while (~scanf("%d", &n)) { init(n); for (int i = 0; i < n; i++) { scanf("%d%d", &a[i].x, &a[i].y); ma[P(a[i].x, a[i].y)] = i + 1; } uN = n; map <P, int> ::iterator it; for (int i = 0; i < n; i++) { for (int j = -5; j <= 5; j++) { for (int k = -5; k <= 5; k++) { if (j * j + k * k > 25) continue; if (j == 0 && k == 0) continue; P nxt; nxt.first = a[i].x + j, nxt.second = a[i].y + k; it = ma.find(nxt); if (it->second) G[i].push_back(it->second - 1); } } } int res = MaxMatch() / 2; if (res == n) puts("-1"); else printf("%d\n", n - res); } return 0;}
0 0
- FZU 2194 星系碰撞(二分图匹配)
- 【二分匹配】 FZU 2194 星系碰撞 HK算法
- FZU - 2194 星系碰撞
- fzu 2039(二分图匹配)
- FZU 星系碰撞 最大独立集 匈牙利算法
- FZU - 2039 Pets(二分图匹配/匈牙利算法)
- FZU 2039 Pets 二分图匹配
- FZU 2039 Pets【二分匹配】
- FZU - 2039 Pets (二分图匹配 2011年全国大学生程序设计邀请赛(福州))
- FZU 2232 炉石传说 (二分图的最大匹配)
- FZU 2039-Pets(二分图_最大匹配)
- FZU 2232 炉石传说(二分图最大匹配)
- FZU 2039 Pets(二分匹配裸题)
- FZU 2039 二分图
- HDU2063--过山车(二分匹配,二分图)
- poj2356(二分图匹配)
- 二分图(行列匹配)
- 二分图(最大匹配)
- 梅森旋转随机数生成实例
- 【Android SDK程序逆向分析与破解系列】之二:Android可执行程序DEX分析(一)
- java类型强制转换
- cvHaarDetectObjects参数意义
- iPhone iPad 各种控件默认高度
- FZU 2194 星系碰撞(二分图匹配)
- Cocos2dx 3.3 遇到的问题
- Javascript 初学者应知的 24 条最佳实践
- OpenCV: OpenCV中IplImage图像格式
- 剑指offer-8 旋转数组的最小数字
- 调试打断点无效解决方法
- CAPropertyAnimation additive
- 一个简单的auth perl程序
- Eclipse中如何查看andriod apk真机运行的日志