Uvalive 7037 The Problem Needs 3D Arrays(最大密度子圖)
阿新 • • 發佈:2018-10-06
註意 最大密度子圖 ray bit pro d+ ext 一段 size
題意:給一段子序列,定義密度:子序列中的逆序對數/子序列的長度
求這個序列的對大密度.
分析:將序列中的每個位置視作點,逆序對\(<i,j>\)之間表示點i與點j之間有一條無向邊.所以就轉化為了最大密度子圖的模型.
#include<bits/stdc++.h> using namespace std; #define eps 1e-7 #define INF 0x3f3f3f3f const int MAXN=1010;//點數的最大值 const int MAXM=400010;//邊數的最大值 #define captype double struct 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]<n){ if(u==eNode){ captype Min=INF ; int inser; for(int i=pre[u]; i!=-1; i=pre[edges[i^1].to]) if(Min>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; }
Uvalive 7037 The Problem Needs 3D Arrays(最大密度子圖)