2014年西安区域赛C The Problem Needs 3D Arrays
2015-05-26 20:29
176 查看
题意:给定一个1-n的排列,它的一个子序列(不一定连续)设为S,令这个子序列的逆序对为R(S),长度为L(S)。请找到一个S,使得R(S)L(S)\frac{R(S)}{L(S)}最大。
题解:两个数字如果有逆序关系则连边,跑一遍最大密度子图就是答案。
题解:两个数字如果有逆序关系则连边,跑一遍最大密度子图就是答案。
#include<iostream> #include<cstdio> #include<queue> using namespace std; #define REP(i,n) for((i)=0;(i)<(int)(n);(i)++) #define snuke(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++) #define eps 1e-10 typedef double F; #define F_INF (1e20) #define MAXV 10000 #define MAXE 80*10000// E*2! F cap[MAXE],flow[MAXE]; int to[MAXE],_prev[MAXE],last[MAXV],used[MAXV],level[MAXV]; struct MaxFlow{ int V,E; MaxFlow(int n){ int i; V=n;E=0; REP(i,V) last[i]=-1; } void add_edge(int x,int y,F f){ cap[E]=f;flow[E]=0;to[E]=y;_prev[E]=last[x];last[x]=E;E++; cap[E]=0;flow[E]=0;to[E]=x;_prev[E]=last[y];last[y]=E;E++; } bool bfs(int s,int t){ int i; REP(i,V) level[i]=-1; queue<int> q; q.push(s);level[s]=0; while(!q.empty()){ int x=q.front();q.pop(); for(i=last[x];i>=0;i=_prev[i]) if(level[to[i]]==-1&&cap[i]>flow[i]) {q.push(to[i]);level[to[i]]=level[x] + 1;} } return (level[t]!=-1); } F dfs(int v,int t,F f){ int i; if(v==t) return f; for(i=used[v];i>=0;used[v]=i=_prev[i]) if(level[to[i]]>level[v]&&cap[i]>flow[i]){ F tmp=dfs(to[i],t,min(f,cap[i]-flow[i])); if(tmp>0) {flow[i]+=tmp;flow[i^1]-=tmp;return tmp;} } return 0; } F maxflow(int s,int t){ int i; while(bfs(s,t)){ REP(i,V) used[i]=last[i]; while(dfs(s,t,F_INF) !=0); } F ans=0; for(i=last[s];i>=0;i=_prev[i]) ans+=flow[i]; return ans; } }; int n,m; template<typename __ll> inline void read(__ll &m) { __ll x=0,f=1;char ch=getchar(); while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} m=x*f; } struct edg{ int u,v; }E[MAXE]; bool check(double k){ int i; MaxFlow f(m+n+2); for(i=1;i<=n;i++) f.add_edge(i,m+n+1,k); for(i=1;i<=m;i++) f.add_edge(n+i,E[i].u,F_INF),f.add_edge(n+i,E[i].v,F_INF),f.add_edge(0,n+i,1); double ans=m-f.maxflow(0,m+n+1); return ans<eps; } int a[111]; int main() { int i,j,u,v,T,cas=1; cin>>T; while(T--){ cin>>n; m=0; for(i=1;i<=n;i++) read(a[i]); for(i=1;i<=n;i++) for(j=i+1;j<=n;j++) if(a[i]>a[j]) E[++m].u=i,E[m].v=j; double l=0,r=m,mid; while(l+eps<=r){ mid=(l+r)/2; if(check(mid)) r=mid; else l=mid; } printf("Case #%d: %.10lf\n",cas++,l); } }
相关文章推荐
- 2014年西安区域赛总结Accelerator
- CF GYM 100548 The Problem Needs 3D Arrays(2014ACM西安现场赛Problem C)
- 2017西安ICPC区域赛小结
- 14西安区域赛总结帖
- UVAlive 7037 - The Problem Needs 3D Arrays(网络流‘最大密度子图)
- 2014年ACM亚洲区域赛2站1铜收场
- 2017ACM-ICPC区域赛(西安)赛后感
- hdu5579 2015区域赛上海赛区G.Game of Arrays
- HDU5014 2014ACM-ICPC 亚洲区域赛西安赛区网络赛H题 Number Sequence
- 2014ACM-ICPC亚洲区域西安赛区 G题 / GYM 100548 G
- HDU5007——Post Robot(2014 年 西安区域赛)
- 《zw版·Halcon-delphi系列原创教程》 3d汽车模型自动区域分割
- 2017 ACM区域赛(西安) 参赛流水账
- [最大密度子图 最小割] ACM 2014 Xian C The Problem Needs 3D Arrays
- 2014年北京区域赛 hdu 5037 贪心
- unity 3d 在限定区域内 实现文字拖动翻页
- matlab,针对图像,如何获得 3D 连通区域的外接长方体
- 2014年GDG西安 -- DevFest Season1
- 写在新年的第一天,3D程序的2014年展望
- [2014 ACM 西安区域赛]PalindromicTree 回文树