题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5049
思路:逆序对个数除以序列长度。类比最大密度子图边数除以点数。则若<i,j>为一逆序对,则连边<i,j>。则边数为逆序对个数,点数为序列长度,求出最大密度子图即可。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define debu
using namespace std;
const double eps=1e-7;
const int INF=0x3f3f3f3f;
const int maxn=1e4+50;
const int maxm=5e4+50;
int n,tot,s,t,num;
int adj[maxn],dis[maxn];
int a[maxn],q[maxn],d[maxn];
struct edge
{
int v,pre;
double w;
} e[maxm];
struct node
{
int u,v;
} E[maxn];
void Insert(int u,int v,double w)
{
e[num]=(edge){v,adj[u],w},adj[u]=num++;
e[num]=(edge){u,adj[v],0},adj[v]=num++;
}
int bfs()
{
int i,x,v,head=0,tail=0;
memset(dis,0,sizeof(dis));
dis[s]=1;
q[++tail]=s;
while(head!=tail)
{
x=q[head=(head+1)%maxn];
for(i=adj[x]; ~i; i=e[i].pre)
if(e[i].w>0&&!dis[v=e[i].v])
{
dis[v]=dis[x]+1;
if(v==t) return 1;
q[tail=(tail+1)%maxn]=v;
}
}
return 0;
}
double dfs(int x,double limit)
{
if(x==t) return limit;
int v;
double tmp,cost=0;
for(int i=adj[x]; ~i&&cost<limit; i=e[i].pre)
if(e[i].w>0&&dis[x]==dis[v=e[i].v]-1)
{
tmp=dfs(v,min(limit-cost,e[i].w));
if(tmp)
{
e[i].w-=tmp;
e[i^1].w+=tmp;
cost+=tmp;
}
else dis[v]=-1;
}
return cost;
}
double Dinic()
{
double ans=0.0;
while(bfs()) ans+=dfs(s,INF);
return ans;
}
int ok(double mid)
{
memset(adj,-1,sizeof(adj));
num=0,s=0,t=n+1;
for(int i=1; i<=tot; i++)
{
Insert(E[i].v,E[i].u,1);
Insert(E[i].u,E[i].v,1);
}
for(int i=1; i<=n; i++)
{
Insert(s,i,tot);
Insert(i,t,tot*1.0+2*mid-1.0*d[i]);
}
return (1.0*tot*n-Dinic())>=eps;
}
int main()
{
#ifdef debug
freopen("in.in","r",stdin);
#endif // debug
int t,cas=0;
scanf("%d",&t);
while(t--)
{
printf("Case #%d: ",++cas);
scanf("%d",&n);
tot=0;
memset(d,0,sizeof(d));
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])
{
tot++;
E[tot].u=i;
E[tot].v=j;
d[i]++,d[j]++;
}
}
double l=0,r=tot,mid,ans=0.0;
while(r-l>eps)
{
mid=(l+r)/2.;
if(ok(mid))
{
ans=mid;
l=mid;
}
else r=mid;
}
printf("%f\n",ans);
}
return 0;
}