UVALive 7037 (最大密度子图 网络流)
来源:互联网 发布:知乎 桥本环奈 编辑:程序博客网 时间:2024/04/29 22:35
每个数都看成一个节点,每个逆序对之间的节点连边,于是只需要求出这个图的最大密度子图,可以用最小割模型解决.
#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <queue>using namespace std;const double INF = 1e8;#define maxn 1511#define maxm 2111111#define eps 1e-10#define type doubleint n, m, x, N;int s, t;struct Edge{ int from, to,next; type cap,flow; void get(int u,int a,int b,type c,type d) { from = u; to = a; next = b; cap = c; flow = d; }}edge[maxm];int tol;int head[maxn];int gap[maxn],dep[maxn],pre[maxn],cur[maxn];void init(){ tol=0; memset(head,-1,sizeof(head));}void add_edge(int u,int v,type w,type rw=0){ //cout << u << " " << v << " " << w << endl; edge[tol].get(u, v,head[u],w,0);head[u]=tol++; edge[tol].get(v, u,head[v],rw,0);head[v]=tol++;}type sap(int start,int end,int N){ memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u=start; pre[u]=-1; gap[0]=N; type ans=0; while(dep[start]<N) { if(u==end) { type Min=INF; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) if(Min>edge[i].cap-edge[i].flow) Min=edge[i].cap-edge[i].flow; for(int i=pre[u];i!=-1;i=pre[edge[i^1].to]) { edge[i].flow+=Min; edge[i^1].flow-=Min; } u = start; ans+=Min; continue; } bool flag=false; int v; for(int i=cur[u];i !=-1;i=edge[i].next) { v=edge[i].to; if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u]) { flag=true; cur[u]=pre[v]=i; break; } } if(flag) { u=v; continue; } int Min=N; for(int i=head[u];i!=-1;i=edge[i].next) if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min) { Min=dep[edge[i].to]; cur[u]=i; } gap[dep[u]]--; if(!gap[dep[u]]) return ans; dep[u]=Min+1; gap[dep[u]]++; if(u!=start) u=edge[pre[u]^1].to; } return ans;}int degree[maxn];int num[maxn];type f (type g) { init (); s = 0, t = n+1, N = n+2; double U = 1.0*m; for (int i = 1; i <= n; i++) { for (int j = 1; j < i; j++) { if (num[j] > num[i]) { add_edge (i, j, 1); add_edge (j, i, 1); } } } for (int i = 1; i <= n; i++) add_edge (s, i, U); for (int i = 1; i <= n; i++) add_edge (i, t, U+2*g-1.0*degree[i]); double ans = sap (s, t, N); ans = (U*n-ans)/2; return ans;}bool vis[maxn];void dfs (int u) { vis[u] = 1; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (vis[v]) continue; if (edge[i].cap-edge[i].flow > 0 && edge[i].cap > 0) dfs (v); }}int main () { //freopen ("in.txt", "r", stdin); int tt, kase = 0; scanf ("%d", &tt); while (tt--) { scanf ("%d", &n); m = 0; memset (degree, 0, sizeof degree); for (int i = 1; i <= n; i++) { scanf ("%d", &num[i]); for (int j = 1; j < i; j++) { if (num[j] > num[i]) { degree[i]++; degree[j]++; m++; } } } double l = 0, r = 10000; int kk = 50; while (kk--) { double mid = (l+r)/2; double h = f (mid); if (h <= 0) r = mid; else l = mid; } printf ("Case #%d: %.7f\n", ++kase, l); } return 0;}
0 0
- UVALive 7037 (最大密度子图 网络流)
- UVAlive 7037 - The Problem Needs 3D Arrays(网络流‘最大密度子图)
- UvaLive 3709 Hard Life(最大密度子图)
- poj3155(网络流最大密度子图模型)
- 【POJ3155】【网络流】【最大密度子图】Hard Life 题解
- UVALive 7037 The Problem Needs 3D Arrays(最大密度子图)
- Uvalive 7037 The Problem Needs 3D Arrays(最大密度子图)
- UVa 7037 ACM/ICPC 2014 Xian(网络流+最大密度子图)
- UvaLive 7037 The Problem Needs 3D Arrays 【最大密度子图-最大权闭合子图做法】
- (最大密度子图)
- 最大密度子图
- poj 3155 Hard Life 网络流——最大密度子图
- 计蒜客-腾讯狼人杀(网络流+最大密度子图)
- POJ3155-最大密度子图
- POJ3155【最大密度子图】
- poj3155 最大密度子图
- 最大密度闭合子图
- 最大密度子图poj3155
- Viewpager结合RadioGroup切换的卡顿,不流畅问题
- Anroid开发:友盟分享SDK v5使用指南(Android Studio)
- 【iOS开发系列】collectionView头部悬浮
- mysql使用技巧(更新中)
- RadioGroup调用setcheck(bool)方法时,onCheckedChanged方法被执行多次解决办法
- UVALive 7037 (最大密度子图 网络流)
- Android RelativeLayout 属性
- [leetcode]Path Sum II
- CSS_样式、选择器、继承_tag
- [ios]使用代码进行故事板创建的视图的跳转 ?
- C++面试题30道
- iOS-友盟消息推送的快速实现
- nohup 命令
- 网易互娱2017实习生招聘在线笔试(一)