UVALive 7037:The Problem Needs 3D Arrays(最大密度子图)
题意
给出n个点,每个点有一个值,现在要选择一些点的集合,使得(选择的点生成的逆序对数目)/(选择的点的数量)的比率最大。
思路
点与点之间生成一个逆序对可以看做是得到一个边,那么就是分数规划问题|E|/|V|,即求最大密度子图。
先处理出所有的逆序对,然后把这些逆序对看作边。
二分枚举 h(g) = |E| - g * |V|中的g,h(g)为递减函数,把g看做点权,转化为最大权闭合图处理,当 h(g) 为0时,得到最优解,这时候的g就是答案。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const int N = 11111;
const double eps = 1e-8;
const double inf = 1000000000;
struct Edge {
int u, v, nxt;
double cap;
} edge[N*4];
int S, T, n, m, a[N], head[N], tot, pre[N], cur[N], gap[N], dis[N];
pii p[N];
void Add(int u, int v, double cap) {
edge[tot] = (Edge) { u, v, head[u], cap }; head[u] = tot++;
edge[tot] = (Edge) { v, u, head[v], 0 }; head[v] = tot++;
}
void BFS(int T) {
memset(dis, INF, sizeof(dis));
memset(gap, 0, sizeof(gap));
queue<int> que;
que.push(T); dis[T] = 0; gap[0] = 1;
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(dis[v] != INF) continue;
dis[v] = dis[u] + 1;
gap[dis[v]]++;
que.push(v);
}
}
}
double ISAP(int S, int T, int n) {
BFS(T);
memcpy(cur, head, sizeof(cur));
int u = pre[S] = S, i, index;
double ans = 0, flow;
while(dis[S] < n) {
if(u == T) {
flow = inf; index = u;
for(u = S; u != T; u = edge[cur[u]].v)
if(flow > edge[cur[u]].cap) flow = edge[cur[u]].cap, index = u;
for(u = S; u != T; u = edge[cur[u]].v)
edge[cur[u]].cap -= flow, edge[cur[u]^1].cap += flow;
ans += flow; u = index;
}
for(i = cur[u]; ~i; i = edge[i].nxt)
if(dis[edge[i].v] == dis[u] - 1 && edge[i].cap > 0) break;
if(~i) {
cur[u] = i; pre[edge[i].v] = u; u = edge[i].v;
} else {
if(--gap[dis[u]] == 0) break;
int md = n + 1;
for(i = head[u]; ~i; i = edge[i].nxt)
if(dis[edge[i].v] < md && edge[i].cap > 0)
cur[u] = i, md = dis[edge[i].v];
gap[dis[u] = md + 1]++;
u = pre[u];
}
}
return ans;
}
void Build(double g) {
memset(head, -1, sizeof(head)); tot = 0;
for(int i = 1; i <= n; i++) Add(i, T, g);
for(int i = 1; i <= m; i++) {
Add(S, i + n, 1);
Add(i + n, p[i].first, inf);
Add(i + n, p[i].second, inf);
}
}
int main() {
int t; scanf("%d", &t);
for(int cas = 1; cas <= t; cas++) {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
m = 0;
for(int i = 1; i <= n; i++)
for(int j = i + 1; j <= n; j++)
if(a[i] > a[j]) p[++m] = {i, j};
double l = 0, r = m + 1, now;
S = 0, T = n + m + 1;
while(r - l >= eps) {
double mid = (l + r) / 2;
Build(mid);
now = 1.0 * m - ISAP(S, T, T + 1);
if(now < eps) r = mid;
else l = mid;
}
printf("Case #%d: %.12f\n", cas, l);
}
return 0;
}
/*
1
5
3 4 2 5 1
Case #1: 1.250000000000
*/
UVALive 7037:The Problem Needs 3D Arrays(最大密度子图)的更多相关文章
- Uvalive 7037 The Problem Needs 3D Arrays(最大密度子图)
题意:给一段子序列,定义密度:子序列中的逆序对数/子序列的长度 求这个序列的对大密度. 分析:将序列中的每个位置视作点,逆序对\(<i,j>\)之间表示点i与点j之间有一条无向边.所以就转 ...
- Gym - 100548C The Problem Needs 3D Arrays
Problem C. The Problem Needs 3D Arrays Time Limit: 6000MS Memory Limit: 262144KB 64bit IO Format: ...
- 2014 西安 The Problem Needs 3D Arrays
The Problem Needs 3D Arrays 题意:给你n个数, 然后1-n的数, 然后要求按顺序选出m个数, 求 逆序数/m 个数的 最大值是多少. 题解:裸的最大密度子图.逆序的2个数建 ...
- Gym - 100548C The Problem Needs 3D Arrays (最大密度子图)
TK在大多数 Unix平台.Windows平台和Macintosh系统都是预装好的,TKinter 模块是 Tk GUI 套件的标准Python接口.可实现Python的GUI编程. Tkinter模 ...
- 14西安区域赛C - The Problem Needs 3D Arrays
最大密度子图裸题,详情请见胡博涛论文: https://wenku.baidu.com/view/986baf00b52acfc789ebc9a9.html 不加当前弧优化t到死= = //#prag ...
- POJ 3155 Hard Life 最大密度子图 最大权闭合图 网络流 二分
http://poj.org/problem?id=3155 最大密度子图和最大权闭合图性质很相近(大概可以这么说吧),一个是取最多的边一个是取最多有正贡献的点,而且都是有选一种必须选另一种的限制,一 ...
- POJ 3155 Hard Life(最大密度子图)
裸题.输入一个无向图,输出最大密度子图(输出子图结点数和升序编号). 看了<最小割模型在信息学竞赛中的应用——胡伯涛>的一部分,感觉01分数规划问题又是个大坑.暂时还看不懂. 参考http ...
- poj 3155 最大密度子图
思路: 这个还是看的胡伯涛的论文<最小割在信息学竞赛中的应用>.是将最大密度子图问题转化为了01分数规划和最小割问题. 直接上代码: #include <iostream> # ...
- POJ3155 Hard Life [最大密度子图]
题意:最大密度子图 #include<iostream> #include<cstdio> #include<cstring> #include<algo ...
随机推荐
- XF警告试图
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- ASP.NET Core SameSite 设置引起 Cookie 在 QQ 浏览器中不起作用
最近在发布了基于 ASP.NET Core 实现的新版登录页面之后,陆陆续续地接到用户反馈登录时 Antiforgery Token 总是验证失败. 日志中记录的对应错误是 Antiforgery t ...
- 1 min 数据查询 SQL 优化
问题 前几天线上数据库 IOPS 飙升,一直居高不下,最近并没有升级.遂查看数据库正在执行的 SQL 语句,发现有个查询离线设备的语句极其缓慢. 探寻原因 SELECT o.* FROM ( SELE ...
- C# 读取大文件 (可以读取3GB大小的txt文件)
原文:C# 读取大文件 (可以读取3GB大小的txt文件) 在处理大数据时,有可能 会碰到 超过3GB大小的文件,如果通过 记事本 或 NotePad++去打开它,会报错,读不到任何文件. 如果你只是 ...
- jq自定义下拉菜单,在点击非当前下拉菜单区域时,关闭下拉菜单(点击事件的对象不是目标元素本身)
jq自定义下拉菜单,在点击非当前下拉菜单区域时,关闭下拉菜单(点击事件的对象不是目标元素本身) //点击非当前下拉菜单区域时,关闭下拉菜单 $(document).mousedown(function ...
- github网页
GitHub主页 创建仓库 想必大家都有自己的Github账号吧,没有的可以到GitHub官网注册账号,注册完后,我们来下一步,在我们的GitHub上面右上角的New repository来创建一个仓 ...
- Cordova页面加载外网图片失败,Refused to load the image
原文:Cordova页面加载外网图片失败,Refused to load the image 1.使用Cordova页面加载外网图片失败,抛出异常 Refused to load the image ...
- C# 获得设备usb信息
原文:C# 获得设备usb信息 本文告诉大家如何获得设备的usb来进行判断是否有哪些usb和找不到usb可能是什么. 需要在项目右击引用,点击程序集,搜索 System.Management 然后安装 ...
- Android零基础入门第6节:配置优化SDK Manager,正式约会女神
原文:Android零基础入门第6节:配置优化SDK Manager,正式约会女神 在前几期中总结分享了Android的前世今生.Android 系统架构和应用组件那些事.带你一起来聊一聊Androi ...
- Android零基础入门第3节:带你一起来聊一聊Android开发环境
原文:Android零基础入门第3节:带你一起来聊一聊Android开发环境 工欲善其事,必先利其器.Android开发人员在自己的计算机上编写和测试应用程序,然后将其部署到实际的设备上,那首先必不可 ...