UVALive 7037 The Problem Needs 3D Arrays(网络流)

来源:互联网 发布:云数据库怎么使用 编辑:程序博客网 时间:2024/06/05 19:25

思路:将所有逆序对连边,就是最大密度子图问题,参照论文~


#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int maxn = 8010;const int maxm = 1000010;const int INF = 1e9;const double eps = 1e-12;struct Edge{int to,next;double cap,flow;}edge[maxm];int tot;int head[maxn];int gap[maxn],dep[maxn],cur[maxn],q[maxn];void init(){tot = 0;memset(head,-1,sizeof(head));}void addedge(int u,int v,double w,double rw = 0){edge[tot].to = v;edge[tot].cap=w;edge[tot].flow = 0;edge[tot].next = head[u];head[u]=tot++;edge[tot].to = u;edge[tot].cap = rw;edge[tot].flow = 0;edge[tot].next = head[v];head[v]=tot++;}void bfs(int st,int ed){    memset(dep,-1,sizeof(dep));memset(gap,0,sizeof(gap));gap[0]=1;int front = 0,rear=0;dep[ed]=0;q[rear++]=ed;while(front!=rear){int u = q[front++];for(int i = head[u];i!=-1;i=edge[i].next){int v = edge[i].to;if(dep[v]!=-1)continue;q[rear++]=v;dep[v]=dep[u]+1;gap[dep[v]]++;}}}int s[maxn];double sap(int st,int ed,int N){    bfs(st,ed);memcpy(cur,head,sizeof(head));int top = 0;int u = st;double ans = 0;while(dep[st] < N){if (u==ed){double Min = INF;int inser;for(int i = 0;i<top;i++)if(Min > edge[s[i]].cap-edge[s[i]].flow){                     Min = edge[s[i]].cap - edge[s[i]].flow; inser = i;}for(int i = 0;i<top;i++){edge[s[i]].flow+=Min;edge[s[i]^1].flow-=Min;}ans+=Min;top = inser;u = edge[s[top]^1].to;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]=i; break;}}if(flag){s[top++]=cur[u];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!=st)u = edge[s[--top]^1].to;}return ans;}struct Node{int u,v;}v[maxn];int n,m;int a[maxn];bool check(double mid){init();int s=  0,t=n+m+1;for(int i = 1;i<=m;i++)addedge(s,i,1);for(int i = 1;i<=n;i++)addedge(i+m,t,mid);for(int i = 1;i<=m;i++){addedge(i,v[i].u+m,INF);addedge(i,v[i].v+m,INF);}double ans = sap(s,t,t+1);return 1.0*m-ans<eps;}int d[maxn];int main(){     int T,cas=1;scanf("%d",&T);while(T--){printf("Case #%d: ",cas++);m = 1;memset(d,0,sizeof(d));scanf("%d",&n);for (int i = 1;i<=n;i++)scanf("%d",&a[i]);for (int i = 1;i<=n;i++)for (int j = i+1;j<=n;j++){if(a[i]>a[j]){v[m].u = i;v[m].v = j;d[v[m].u]++;d[v[m].v]++;m++;}}m--;double l = 0;double r = m;for(int cnt = 1;cnt<=50;cnt++){double mid = (l+r)/2;if (check(mid))r = mid;elsel = mid;}printf("%.12lf\n",l);}}


0 0
原创粉丝点击