题目链接

题意

给出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(最大密度子图)的更多相关文章

  1. Uvalive 7037 The Problem Needs 3D Arrays(最大密度子图)

    题意:给一段子序列,定义密度:子序列中的逆序对数/子序列的长度 求这个序列的对大密度. 分析:将序列中的每个位置视作点,逆序对\(<i,j>\)之间表示点i与点j之间有一条无向边.所以就转 ...

  2. Gym - 100548C The Problem Needs 3D Arrays

    Problem C.   The Problem Needs 3D Arrays Time Limit: 6000MS Memory Limit: 262144KB 64bit IO Format: ...

  3. 2014 西安 The Problem Needs 3D Arrays

    The Problem Needs 3D Arrays 题意:给你n个数, 然后1-n的数, 然后要求按顺序选出m个数, 求 逆序数/m 个数的 最大值是多少. 题解:裸的最大密度子图.逆序的2个数建 ...

  4. Gym - 100548C The Problem Needs 3D Arrays (最大密度子图)

    TK在大多数 Unix平台.Windows平台和Macintosh系统都是预装好的,TKinter 模块是 Tk GUI 套件的标准Python接口.可实现Python的GUI编程. Tkinter模 ...

  5. 14西安区域赛C - The Problem Needs 3D Arrays

    最大密度子图裸题,详情请见胡博涛论文: https://wenku.baidu.com/view/986baf00b52acfc789ebc9a9.html 不加当前弧优化t到死= = //#prag ...

  6. POJ 3155 Hard Life 最大密度子图 最大权闭合图 网络流 二分

    http://poj.org/problem?id=3155 最大密度子图和最大权闭合图性质很相近(大概可以这么说吧),一个是取最多的边一个是取最多有正贡献的点,而且都是有选一种必须选另一种的限制,一 ...

  7. POJ 3155 Hard Life(最大密度子图)

    裸题.输入一个无向图,输出最大密度子图(输出子图结点数和升序编号). 看了<最小割模型在信息学竞赛中的应用——胡伯涛>的一部分,感觉01分数规划问题又是个大坑.暂时还看不懂. 参考http ...

  8. poj 3155 最大密度子图

    思路: 这个还是看的胡伯涛的论文<最小割在信息学竞赛中的应用>.是将最大密度子图问题转化为了01分数规划和最小割问题. 直接上代码: #include <iostream> # ...

  9. POJ3155 Hard Life [最大密度子图]

      题意:最大密度子图 #include<iostream> #include<cstdio> #include<cstring> #include<algo ...

随机推荐

  1. Delphi中返回类型为string的函数的一个陷阱(不是很懂)

    如果类的一个成员函数的返回值是string类型,需要注意一个问题 其返回值可能是错误的 例如函数的实现如下 function GetString( s: string ): string;begin  ...

  2. Git Bash Cmd命令笔记

    生成ssh公钥ssh-keygen -t rsa -C "xxxxx@xxxxx.com" # 三次回车即可生成 ssh key 查看你的public keycat ~/.ssh/ ...

  3. linux虚拟机上svn客户端连接问题

    在虚拟机上搭建好的svn,本地连接居然不行,原来是防火墙端口没开造成的. 修改配置文件:vi /etc/sysconfig/iptables # Generated by iptables-save ...

  4. 常用的shell(备份数据库、备份网站、切割访问日志)

    备份网站程序 #!/bin/bash /bin/tar czf /mnt/backup_website/web_$(date +%Y%m%d_%H%M%S).gz.tar /mnt/wwwroot/w ...

  5. C# 事件详解

    1.事件的本质是什么 答:事件是委托的包装器,就像属性是字段的包装器一样 2.为什么有了委托还有有事件 委托可以被访问就可以被执行,事件则只能在类的内部执行 3.事件要怎么声明 a.明一个委托 //委 ...

  6. Vue-cli入门(一)——项目搭建

    Vue-cli入门(一)——项目搭建 前言: Vue-cli是一款基于vue的项目脚手架工具,其集成了webpack环境和主要的依赖,对于我们的项目搭建.开发.打包.维护管理等都是非常的方便. 主要内 ...

  7. OPENGL---Ps 径向模糊算法(glsl)

    原文:OPENGL---Ps 径向模糊算法(glsl) 本文转载自:  http://blog.csdn.net/zx6733090/article/details/40311689 功能本人之前也介 ...

  8. Java底层知识学习:Bytecode and JMM

    最近在跟着耗子哥的程序员练级指南学习Java底层知识,结合<深入理解Java虚拟机>这本书在看,写笔记,看资料,成长中…… 目前看完了第二章JMM和各内存区OOM的情况 一篇图文并茂介绍字 ...

  9. 微信小程序把玩(十)swiper组件

    原文:微信小程序把玩(十)swiper组件 Android写过轮播图的痛楚只有写过的知道,相对还是比较麻烦的,并没有一个轮播图组件,有个ViewPage也需要自己定制,IOS则多用UIScroller ...

  10. 微信小程序把玩(三十二)Image API

    原文:微信小程序把玩(三十二)Image API 选择图片时可设置图片是否是原图,图片来源.这用的也挺常见的,比如个人中心中设置头像,可以与wx.upLoadFile()API使用 主要方法: wx. ...