您的位置:首页 > 其它

2014西安赛区C题

2015-10-29 22:49 155 查看
将A[i]同他后面比他小的建边,然后求最大密度子图

#include <iostream>
#include <algorithm>
#include <string.h>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const int maxn=105;
const double eps=0.00000001;
const double INF=100000005;
vector<int>ans;
struct Dinic
{
struct Edge
{
int from,to;
double cap,flow;
Edge(int cfrom=0,int cto=0,double ccap=0,double cflow=0)
{
from=cfrom; to=cto; cap=ccap; flow=cflow;
}
};
int n,m,s,t;
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
void init(int n)
{
this->n=n;
m=0;
edges.clear();
for(int i=0; i<=n; i++)G[i].clear();
}
void AddEdge(int from,int to,double cap)
{
edges.push_back(Edge(from,to,cap,0));
edges.push_back(Edge(to,from,0,0));
m+=2;
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BFS()
{
memset(vis,false,sizeof(vis));
queue<int>Q;
Q.push(s);
d[s]=0;
vis[s]=1;
while(!Q.empty())
{
int x=Q.front(); Q.pop();
for(int i=0; i<G[x].size(); i++)
{
Edge &e =edges[G[x][i]];
if(vis[e.to]==false&&e.cap>e.flow)
{
vis[e.to]=1;
d[e.to]=d[x]+1;
Q.push(e.to);
}
}
}
return vis[t];
}
double DFS(int x, double a)
{
if(x==t||a==0)return a;
double flow=0,f;
for(int &i=cur[x]; i<G[x].size(); i++)
{
Edge &e=edges[G[x][i]];
if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
{
e.flow+=f;
edges[G[x][i]^1].flow-=f;
flow+=f;
a-=f;
if(a==0)break;
}
}
return flow;
}
double Maxflow(int s,int t)
{
this->s=s; this->t=t;
double flow=0;
while(BFS())
{
memset(cur,0,sizeof(cur));
flow+=DFS(s,INF);
}
return flow;
}
}T;
int d[maxn];
int A[maxn*maxn],B[maxn*maxn];
int N[maxn];
double U;
void build(int n,int m,double g)
{
T.init(n+2);
for(int i=1; i<=n; i++)
{
T.AddEdge(n+1,i,U);
T.AddEdge(i,n+2,U+g*2-d[i]);
}
for(int i=0; i<m; i++)
{
T.AddEdge(A[i],B[i],1);
T.AddEdge(B[i],A[i],1);
}
}
int main()
{
int cas;
scanf("%d",&cas);
for(int cc=1; cc<=cas; cc++)
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&N[i]);
int m=0;
memset(d,0,sizeof(d));
for(int i=1; i<=n; i++)
for(int j=i+1; j<=n; j++)
if(N[i]>N[j]){
d[N[i]]++;d[N[j]]++;
A[m]=N[i];B[m]=N[j]; m++;
}
if(m==0)
{
printf("Case #%d: 0.0000000\n",cc);
continue;
}
double L=0,R=m;
U=m;
while(R-L>=eps)
{
double mid=(L+R)*0.5;
build(n,m,mid);
double ans=T.Maxflow(n+1,n+2);
ans=(U*n-ans)*0.5;
if(ans>0)L=mid;
else R=mid;
}
printf("Case #%d: %.7lf\n",cc,L );
}
return 0;
}
/*
2
5
3 4 2 5 1
5
2 1 3 4 5
*/


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: