LA7037-The Problem Needs 3D Arrays(最大稠密子图)
来源:互联网 发布:粒子群算法应用 编辑:程序博客网 时间:2024/06/05 16:53
题目链接
https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5049
题意
给定一个序列,从里面选出x个数,其中的逆序对数为y,使y / x最大。
思路
将这些序列中的数看做点,其中存在逆序关系的(a[i], a[j])看做一条边,比如3 4 2 5 1。就可以建成如下的一张图:
那么问题就转化成了在图中选出若干个点,使这些点包含的边/这些点数最大。即最大稠密子图
最大稠密子图的求解参见:http://wenku.baidu.com/view/986baf00b52acfc789ebc9a9.html?from=search
其思路就是将最大稠密子图转化为最大权闭合图问题的求解。最大权闭合图求解步骤:
1. 新建源S和汇T,其中权值为正的结点,连一条S->该点的边,容量为该点权值。权值为负的结点,新建一条从该点->T的边,容量为该点权值的绝对值。
2. 对于原来的结点的边的关系,容量全部设为INF
3. 求该图的最小割
4. res = 权值为正的点的权值和 - 最小割
细节
二分的时候M也记得初始化,不然有可能根本没有进入循环,M也没有定义= =
代码
#include <iostream>#include <cstring>#include <stack>#include <vector>#include <set>#include <map>#include <cmath>#include <queue>#include <sstream>#include <iomanip>#include <fstream>#include <cstdio>#include <cstdlib>#include <climits>#include <deque>#include <bitset>#include <algorithm>using namespace std;#define PI acos(-1.0)#define LL long long#define PII pair<int, int>#define PLL pair<LL, LL>#define mp make_pair#define IN freopen("in.txt", "r", stdin)#define OUT freopen("out.txt", "wb", stdout)#define scan(x) scanf("%d", &x)#define scan2(x, y) scanf("%d%d", &x, &y)#define scan3(x, y, z) scanf("%d%d%d", &x, &y, &z)#define sqr(x) (x) * (x)#define pr(x) cout << #x << " = " << x << endl#define lc o << 1#define rc o << 1 | 1#define pl() cout << endlconst int maxn = 5000 + 500;const double INF = 0x3e3e3e3e;const double eps = 1e-8;int n;int a[105];struct Edge { int from, to; double cap, flow; Edge(int u, int v, double c, double f) : from(u), to(v), cap(c), flow(f) { }};struct Dinic { int n, m, s, t; vector<Edge> edges; vector<int> G[maxn]; bool vis[maxn]; int cur[maxn], d[maxn]; void init() { for (int i = 0; i < maxn; i++) G[i].clear(); edges.clear(); } void addedge(int u, int v, double c) { edges.push_back(Edge(u, v, c, 0)); edges.push_back(Edge(v, u, 0, 0)); m = edges.size(); G[u].push_back(m - 2); G[v].push_back(m - 1); } bool bfs() { memset(vis, 0, sizeof(vis)); queue<int> Q; Q.push(s); vis[s] = 1, d[s] = 0; while (!Q.empty()) { int x = Q.front(); Q.pop(); int _s = G[x].size(); for (int i = 0; i < _s; i++) { Edge &e = edges[G[x][i]]; if (!vis[e.to] && e.cap - e.flow > eps) { vis[e.to] = 1; d[e.to] = d[x] + 1; Q.push(e.to); } } } return vis[t]; } double dfs(int x, double a) { if (x == t || a < eps) return a; double flow = 0, f; for (int &i = cur[x]; i < G[x].size(); i++) { Edge &e = edges[G[x][i]]; if (d[e.to] == d[x] + 1) { if (min(a, e.cap - e.flow) > eps) { f = dfs(e.to, min(a, e.cap - e.flow)); e.flow += f; edges[G[x][i] ^ 1].flow -= f; flow += f; a -= f; if (a <= eps) break; } } } return flow; } double max_flow(int s, int t) { this->s = s; this->t = t; double flow = 0; while (bfs()) { memset(cur, 0, sizeof(cur)); flow += dfs(s, INF); } return flow; }};Dinic D;int tot, S, T;void buildgraph() { int offset = n * (n - 1) / 2 + n; S = offset + 2; T = offset + 3; tot = n + 1; for (int i = 0; i < n; i++) { for (int j = i + 1; j < n; j++) { if (a[i] > a[j]) { D.addedge(tot, a[i], INF); D.addedge(tot++, a[j], INF); } } } for (int i = 1; i <= n; i++) D.addedge(i, T, 0); for (int i = n + 1; i < tot; i++) D.addedge(S, i, 1);}bool judge(double x) { for (int v = 1; v <= n; v++) { for (int i = 0; i < D.G[v].size(); i++) { Edge &e = D.edges[D.G[v][i]]; if (e.to == T) e.cap = x; } } for (int i = 0; i < D.edges.size(); i++) { Edge &e = D.edges[i]; e.flow = 0; } double flow = D.max_flow(S, T); double pov = double(tot - n - 1); return (pov - flow) >= eps;}double solve() { D.init(); buildgraph(); int m = tot - n - 1; double L = 0, R = double(m), M = (L + R) / 2; while (R - L > eps) { M = (L + R) / 2.0; if (judge(M)) L = M; else R = M; } return M;}int main() { int T, kase = 0; scan(T); while (T--) { scan(n); for (int i = 0; i < n; i++) scan(a[i]); double res = solve(); printf("Case #%d: %.6lf\n", ++kase, res); } return 0; }
0 0
- LA7037-The Problem Needs 3D Arrays(最大稠密子图)
- UVAlive 7037 - The Problem Needs 3D Arrays(网络流‘最大密度子图)
- UVALive 7037 The Problem Needs 3D Arrays(最大密度子图)
- Uvalive 7037 The Problem Needs 3D Arrays(最大密度子图)
- Uvalive 7037 The Problem Needs 3D Arrays (最大密集子图)
- [最大密度子图 最小割] ACM 2014 Xian C The Problem Needs 3D Arrays
- UvaLive 7037 The Problem Needs 3D Arrays 【最大密度子图-最大权闭合子图做法】
- 2014-2015 ACM-ICPC, Asia Xian Regional Contest C – The Problem Needs 3D Arrays(最大密度子图)
- UVALive 7037 The Problem Needs 3D Arrays(网络流)
- CF GYM 100548 The Problem Needs 3D Arrays(2014ACM西安现场赛Problem C)
- 2014年西安区域赛C The Problem Needs 3D Arrays
- 最大子串问题(The Maximum-subarray Problem)
- 最大子数组(The maximum-subarray problem)
- MUTC 3 D - Cut the cake 最大子矩阵
- Problem D: 渊子赛马
- Problem D. Cross the maze
- Codeforces 776D The Door Problem 二分图判定
- hdu 3861 The King’s Problem (tarjan 算法+二分图最大匹配)
- ZVAL_STRING 和 ZVAL_STRINGL
- codeforces368-A. Brain's Photos
- 大型web系统数据缓存设计
- UVA-213
- 互补滤波姿态估计程序
- LA7037-The Problem Needs 3D Arrays(最大稠密子图)
- [github项目]基于百度地图二次开发实现的车辆监管(包含车辆定位、车辆图片和方向控制,电子围栏,图形绘制等功能)前端实现(不包含后端实现)
- Nearest Common Ancestors
- MongoDB的使用
- 浅谈数据库优化方面的经验
- lua学习(1)_____配置lua运行环境
- oracle 服务启动TNSLSNR.exe占用8080端口的问题
- codeforces-368 B. Bakery
- 英文求职信 规范