博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Uvalive 7037 The Problem Needs 3D Arrays(最大密度子图)
阅读量:4978 次
发布时间:2019-06-12

本文共 3475 字,大约阅读时间需要 11 分钟。

题意:给一段子序列,定义密度:子序列中的逆序对数/子序列的长度

求这个序列的对大密度.
分析:将序列中的每个位置视作点,逆序对\(<i,j>\)之间表示点i与点j之间有一条无向边.所以就转化为了最大密度子图的模型.

#include
using namespace std;#define eps 1e-7#define INF 0x3f3f3f3fconst int MAXN=1010;//点数的最大值const int MAXM=400010;//边数的最大值#define captype doublestruct Edge{ int from,to,next; captype cap;};struct SAP_MaxFlow{ Edge edges[MAXM]; int tot,head[MAXN]; int gap[MAXN]; int dis[MAXN]; int cur[MAXN]; int pre[MAXN]; void init(){ tot=0; memset(head,-1,sizeof(head)); } void AddEdge(int u,int v,captype c,captype rc=0){ edges[tot] = (Edge){u,v,head[u],c}; head[u]=tot++; edges[tot] = (Edge){v,u,head[v],rc}; head[v]=tot++; } captype maxFlow_sap(int sNode,int eNode, int n){//n是包括源点和汇点的总点个数,这个一定要注意 memset(gap,0,sizeof(gap)); memset(dis,0,sizeof(dis)); memcpy(cur,head,sizeof(head)); pre[sNode] = -1; gap[0]=n; captype ans=0; int u=sNode; while(dis[sNode]
edges[i].cap){ Min=edges[i].cap; inser=i; } for(int i=pre[u]; i!=-1; i=pre[edges[i^1].to]){ edges[i].cap-=Min; edges[i^1].cap+=Min; } ans+=Min; u=edges[inser^1].to; continue; } bool flag = false; int v; for(int i=cur[u]; i!=-1; i=edges[i].next){ v=edges[i].to; if(edges[i].cap>0 && dis[u]==dis[v]+1){ flag=true; cur[u]=pre[v]=i; break; } } if(flag){ u=v; continue; } int Mind= n; for(int i=head[u]; i!=-1; i=edges[i].next) if(edges[i].cap>0 && Mind>dis[edges[i].to]){ Mind=dis[edges[i].to]; cur[u]=i; } gap[dis[u]]--; if(gap[dis[u]]==0) return ans; dis[u]=Mind+1; gap[dis[u]]++; if(u!=sNode) u=edges[pre[u]^1].to; //退一条边 } return ans; }}F;int N, M;int S,T;int deg[MAXN];int ed[MAXM][2];bool check(double mid){ F.init(); S = 0, T = N+1; for(int i=1;i<=N;++i){ F.AddEdge(S,i,M*1.0); F.AddEdge(i,T,1.0*M + 2*mid - deg[i]); } for(int i=1;i<=M;++i){ F.AddEdge(ed[i][0],ed[i][1], 1.0); F.AddEdge(ed[i][1],ed[i][0], 1.0); } double hg = ( 1.0 * M * N - F.maxFlow_sap(S,T,T+1)) *0.5; return hg>eps;}int p[MAXN];int main(){ #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif int u,v; int T,cas=1; scanf("%d",&T); while(T--){ printf("Case #%d: ",cas++); scanf("%d",&N); for(int i=1;i<=N;++i) scanf("%d",&p[i]); M = 0 ; memset(deg,0,sizeof(deg)); for(int i=1;i<=N;++i){ for(int j=i+1;j<=N;++j){ if(p[i]>p[j]){ M ++; ed[M][0] = i, ed[M][1] = j; deg[i]++, deg[j]++; } } } double L = 0.0, R = M*1.0; while(R-L>= eps){ double mid = (R+L)*0.5; if(check(mid)){ L = mid; }else{ R = mid; } } printf("%.7f\n",L); } return 0;}

转载于:https://www.cnblogs.com/xiuwenli/p/9747146.html

你可能感兴趣的文章
springMVC Controller 参数映射
查看>>
【bzoj题解】2186 莎拉公主的困惑
查看>>
Protocol Buffer学习笔记
查看>>
Update 语句
查看>>
HBuilder打包Android apk 支付不了问题解决
查看>>
poj2594——最小路径覆盖
查看>>
欧拉函数
查看>>
关于SQL2008 “不允许保存更改。您所做的更改要求删除并重新创建以下表。您对无法重新创建的标进行了更改或者启用了‘阻止保存要求重新创建表的更改’” 解决方案...
查看>>
php文件操作(上传文件)2
查看>>
linux内核驱动模型
查看>>
给WebApp加一个“壳”,实现Andriod系统添加到桌面
查看>>
js 浏览器复制功能
查看>>
数据库总编
查看>>
redis 字符串(string)函数
查看>>
杭州电 1372 Knight Moves(全站搜索模板称号)
查看>>
c语言的几个简单memo
查看>>
selenium下打开Chrome报错解决
查看>>
HDU-1150 Machine Schedule(二分图、匈牙利)
查看>>
bzoj3156 防御准备
查看>>
Eclipse修改编码格式
查看>>