码迷,mamicode.com
首页 > 其他好文 > 详细

2014西安赛区C题

时间:2015-10-29 23:10:54      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

将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

 

2014西安赛区C题

标签:

原文地址:http://www.cnblogs.com/Opaser/p/4922061.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!