ZOJ 3760 Treasure Hunting 二分图带权最大独立集 最小割
来源:互联网 发布:千图成像软件 编辑:程序博客网 时间:2024/05/16 06:53
题意:给你一个偶数P和二维坐标上的一些点(x, y) 权值为 x&y 让你选出其中一些点 使得权值和最大 且选中的点集中不存在这样的两点:(a, b)使得gcd(a.x^a.y^b.x^b.y, p) <= 1
思路:由于题意中已经明确说明P为偶数 而两个偶数的最大公约数永远大于1 又发现对于任意两个数A B 只要它俩奇偶性相同 则 A^B必为偶数!所以我们只需要把图中所有点的权值按照奇偶性划分 它的原型不就是二分图带权最大独立集么!!建图方法
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define REP( i, a, b ) for( int i = a; i < b; i++ )#define FOR( i, a, b ) for( int i = a; i <= b; i++ )#define CLR( a, x ) memset( a, x, sizeof a )#define CPY( a, x ) memcpy( a, x, sizeof a )#define BUG puts( "**** BUG ****" )typedef long long LL;const int maxn = 500 + 10;const int maxe = 250000 + 10;const int INF = 0x7fffffff;struct Edge{ int v, c, f; int next; Edge() {} Edge(int v, int c, int f, int next) : v(v), c(c), f(f), next(next) {}};struct Point{ int x, y; Point(int x = 0, int y = 0) : x(x), y(y) {}}point[maxn];struct ISAP{ int n, s, t; int num[maxn], cur[maxn], d[maxn], p[maxn]; int Head[maxn], cntE; int Q[maxn], head, tail; Edge edge[maxe]; void Init(int n){ this -> n = n; cntE = 0; CLR(Head, -1); } void Add(int u, int v, int c){ edge[cntE] = Edge(v, c, 0, Head[u]); Head[u] = cntE++; edge[cntE] = Edge(u, 0, 0, Head[v]); Head[v] = cntE++; } void Bfs(){ CLR(d, -1); CLR(num, 0); d[t] = 0; head = tail = 0; Q[tail++] = t; num[0] = 1; while(head != tail){ int u = Q[head++]; for(int i = Head[u]; ~i; i = edge[i].next){ Edge &e = edge[i]; if(~d[e.v]) continue; d[e.v] = d[u] + 1; Q[tail++] = e.v; num[d[e.v]] ++; } } } LL Maxflow(int s, int t){ this -> s = s; this -> t = t; CPY(cur, Head); Bfs(); int u = p[s] = s; LL flow = 0; while(d[s] < n){ if(u == t){ int f = INF, neck; for(int i = s; i != t; i = edge[cur[i]].v){ if(f > edge[cur[i]].c - edge[cur[i]].f){ f = edge[cur[i]].c - edge[cur[i]].f; neck = i; } } for(int i = s; i != t; i = edge[cur[i]].v){ edge[cur[i]].f += f; edge[cur[i]^1].f -= f; } flow += (LL)f; u = neck; } int ok = 0; for(int i = cur[u]; ~i; i = edge[i].next){ Edge &e = edge[i]; if(e.c > e.f && d[e.v] + 1 == d[u]){ ok = 1; cur[u] = i; p[e.v] = u; u = e.v; break; } } if(!ok){ int m = n - 1; if(--num[d[u]] == 0) break; for(int i = Head[u]; ~i; i = edge[i].next){ Edge &e = edge[i]; if(e.c - e.f > 0 && m > d[e.v]){ cur[u] = i; m = d[e.v]; } } ++num[d[u] = m + 1]; u = p[u]; } } return flow; }}solver;int n, p;Point read_Point(){ Point a; scanf("%d%d", &a.x, &a.y); return a;}int gcd(int a, int b){ return b == 0 ? a : gcd(b, a % b); }void input(){ FOR(i, 1, n) point[i] = read_Point(); }void solve(){ int S = 0, T = n + 1; LL sum = 0; solver.Init(n+2); FOR(i, 1, n){ if((point[i].x ^ point[i].y) & 1){ solver.Add(S, i, point[i].x & point[i].y); FOR(j, 1, n){ if(!((point[j].x^point[j].y)&1)&&gcd(point[i].x^point[i].y^point[j].x^point[j].y, p)<=1) solver.Add(i, j, INF); } } else solver.Add(i, T, point[i].x & point[i].y); sum += (LL)(point[i].x & point[i].y); } printf("%lld\n", sum - solver.Maxflow(S, T));}int main(){ //freopen("in.txt", "r", stdin); while(~scanf("%d%d", &n, &p)){ input(); solve(); } return 0;}
0 0
- ZOJ 3760 Treasure Hunting 二分图带权最大独立集 最小割
- ZOJ 3760 - Treasure Hunting(网络流‘最小割’最大点权独立集)
- zoj 3760 Treasure Hunting 最大独立集
- zoj 3760 Treasure Hunting(最大点权独立集)
- ZOJ 3760 Treasure Hunting 最大点权独立集
- ZOJ 3760 Treasure Hunting(最大流)
- ZOJ 3760 Treasure Hunting(最大流)
- HDU 1569 二分图带权最大独立集 最小割
- zoj 3165 (最小割,最大点权独立集)
- zoj 3165 (最小割,最大点权独立集)
- hdu 1569 &1565 二分图带权最大独立集,最大流最小割定理
- ZOJ 3400 Treasure Hunting
- [网络流24题] 09 方格取数问题 (二分图点权最大独立集,最小割)
- [网络流24题] 24 骑士共存(二分图最大独立集,网络最小割)
- 【网络流二十四题 方格取数问题】【二分图点权最大独立集->最小割】
- 【网络流二十四题 骑士共存问题】【二分图点权最大独立集->最小割】
- HDU3468 Treasure Hunting(中等) [最大流](二分匹配)+最短路
- 最大流最小割(最大点权独立集)
- Android官方培训课程中文版(v0.9.3)
- 我的奋斗之我的构想
- leetcode013
- hdoj 3572 Task Schedule 【最大流 在时间区间建图判断是否满流】
- 比你出身好的人,也在比你更努力着。
- ZOJ 3760 Treasure Hunting 二分图带权最大独立集 最小割
- Java环境内存配置
- J2EE学习(1)—jsp的基础知识汇总
- leetcode014
- Unity3D vuforia SDK 预制物体各组件功能说明
- 【剑指offer】 面试题50: 树中两个结点的最低公共祖先(二叉排序数)
- Holding Your Object 5-14
- 【Asp.net】——Web控件与HTML控件的区别
- Hibernate Merge() 方法