Uvalive 7037 The Problem Needs 3D Arrays(最大密度子图)

题意:给一段子序列,定义密度:子序列中的逆序对数/子序列的长度

求这个序列的对大密度.

分析:将序列中的每个位置视作点,逆序对\(<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;
}

原文地址:https://www.cnblogs.com/xiuwenli/p/9747146.html

时间: 2024-08-06 01:05:26

Uvalive 7037 The Problem Needs 3D Arrays(最大密度子图)的相关文章

CF GYM 100548 The Problem Needs 3D Arrays(2014ACM西安现场赛Problem C)

ProblemC. The Problem Needs 3D Arrays Description A permutation is asequence of integers p1, p2, . . . , pn,consisting of n distinct positive integers and each of them does notexceed n. Assume that r(S) of sequence S denotes the number ofinversions i

Gym - 100548C The Problem Needs 3D Arrays

Problem C.   The Problem Needs 3D Arrays Time Limit: 6000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Description A permutation is a sequence of integers p1,p2,...,pn, consisting of n distinct positive integers and each of them does not e

bnu 51644 Whalyzh&#39;s Problem(网络流,最大密度图) (北师16校赛)

很久以前,当whalyzh同学是一个萌新的时候,遇到了这么一个问题: 给定长为的序列,构造一个只有0和1的长为的序列,使得的值最大. 小Q同学想了一秒钟之后说:这不是一眼题么?然后whalyzh同学瞬间就会了. 过了几天,当whalyzh同学还是一个萌新的时候,遇到了这么一个问题: 给定阶方阵,构造一个只有0和1的的向量,使得的值最大. 小Q同学想了一分钟之后说:这不是一眼题么?然后whalyzh同学瞬间就会了. 又过了几天,当whalyzh仍然是一个萌新的时候,遇到了这么一个问题: 给定阶方阵

POJ 3155 Hard Life(最大密度子图)

POJ 3155 Hard Life 题目链接 最大密度子图模板题 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int MAXNODE = 1105; const int MAXEDGE = 100005; typedef double Type; const Type INF = 1e15;

poj 3155 Hard Life 最大密度子图

Hard Life Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 7598   Accepted: 2191 Case Time Limit: 2000MS   Special Judge Description John is a Chief Executive Officer at a privately owned medium size company. The owner of the company has

poj3155--Hard Life(最大密度子图)

poj3155:题目链接 题目大意:给出了n个点,m条无向边,选一个集合M,要求集合中的边数/点数的最最大 参考:最小割模型在信息学竞赛中的应用 先做了0-1分数规划,然后最大权闭合图,然后是最大密度子图.最大密度子图要用到前两个知识点. 注意:精度问题,这个题的单调性会出现一段为0的值,所以要用二分逼近最左侧的那个,然后在二分完成后,要用low(左边界)再求一次,这样是最精确的 #include <cstdio> #include <cstring> #include <c

POJ Hard Life (最大密度子图)

Hard Life 做该题前需要先了解一些专有名词及定理. 希望你可以亲自看看2007年胡伯涛的论文! 有向图的闭合图(closure): 闭合图内任意点的任意后继也一定还在闭合图中. 题目: 给出N个人,有些人之间有联系,而有联系的两个人被认为是一个整体.如果,把人看作点,把关系看作边,则要求你求出 边 / 点 的比值最大.而这些点边之间必须是一个闭合图. 算法分析: 最大密度子图算法构造: 把原图中的无向边转换成两条有向边,容量为1. 设一源点,连接所有点,容量为U(取m). 设一汇点,所有

POJ 3155 Hard Life(最大密度子图+改进算法)

Hard Life Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 9012   Accepted: 2614 Case Time Limit: 2000MS   Special Judge Description John is a Chief Executive Officer at a privately owned medium size company. The owner of the company has

bzoj 1312 最大密度子图

晕,m=0是要输出1(弄的我还找管理员要数据,但明显题意是叫我们输出0呀) 最大密度子图,把边转换成点,然后二分答案,跑最大权闭合子图判定是否可行. 1 #include <cstdio> 2 #include <cstring> 3 #include <vector> 4 #include <algorithm> 5 #define N 1110 6 #define oo 0x3f3f3f3f 7 using namespace std; 8 9 stru