zoukankan      html  css  js  c++  java
  • Jzoj5669 排列

    有 n 个数 x1 ~xn 。你需要找出它们的一个排列,满足 m 个条件,每个条件形如 x_a 必须在x_b之前。在此基础上,你要最大化这个排列的最大子段和。

    神题,这里先orz一下当场切掉的神犇wjw

    看下数据范围,n<=500感觉是网络流,结果就是

    构图方式,每个点拆开成a[i],b[i]

    如果x[i]>0,那么S->a[i],b[i]->T连权值为x[i]的边

    否则,a[i]->b[i]权值为-x[i]的边

    对于每个限制(x,y) 连a[x]->a[y] 和 b[x]->b[y],容量+inf

    跑一次最小割,用所有正数的和减掉最小割就是答案

    其实割掉三种边的意义是很明显的:

    割掉S->a[i]相当于将i放到最大子段的前面

    割掉a[i]->b[i]相当于将i放入最大子段中

    割掉b[i]->T相当于将i放到最大子段的后面

    #pragma GCC optimize("O3")
    #pragma G++ optimize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 1010
    using namespace std;
    struct edge{ int v,c,nt; } G[N<<3];
    int n,m,cnt=1,ans=0,h[N],cur[N],lvl[N],gap[N],p[N];
    inline void adj(int x,int y,int c){
    	G[++cnt]=(edge){y,c,h[x]}; h[x]=cnt;
    	G[++cnt]=(edge){x,0,h[y]}; h[y]=cnt;
    }
    inline int ISAP(int S,int T){
    	memset(p,-1,sizeof p);
    	memcpy(cur,h,sizeof cur);
    	int x=p[S]=S,fl=0,df=(1<<29); *gap=n+1<<1;
    	for(;lvl[S]<(n+1)<<1;){
    		loop:
    		for(int &i=cur[x],v;i;i=G[i].nt){
    			v=G[i].v;
    			if(G[i].c && lvl[v]+1==lvl[x]){
    				df=min(df,G[i].c); p[v]=x; x=v;
    				if(v==T){
    					fl+=df;
    					for(x=p[v];v!=S;v=x,x=p[x]){
    						G[cur[x]].c-=df;
    						G[cur[x]^1].c+=df;
    					}
    					df=1<<30;
    				}
    				goto loop;
    			}
    		}
    		int dl=n+1<<1;
    		for(int i=h[x];i;i=G[i].nt)
    			if(G[i].c && lvl[G[i].v]<dl){
    				dl=lvl[G[i].v];
    				cur[x]=i;
    			}
    		if(--gap[lvl[x]]==0) break;
    		lvl[x]=dl+1;
    		++gap[lvl[x]]; x=p[x];
    	}
    	return fl;
    }
    int main(){
    	freopen("permutation.in","r",stdin);
    	freopen("permutation.out","w",stdout);
    	scanf("%d%d",&n,&m); 
    	int S=n*2+1,T=n*2+2;
    	for(int x,i=1;i<=n;++i){
    		scanf("%d",&x);
    		if(x>=0){
    			ans+=x;
    			adj(S,i,x);
    			adj(i+n,T,x);
    		} else adj(i,i+n,-x);
    	}
    	for(int x,y;m--;){
    		scanf("%d%d",&x,&y);
    		adj(x,y,1<<20);
    		adj(x+n,y+n,1<<20);
    	}
    	printf("%d
    ",ans-ISAP(S,T));
    }


  • 相关阅读:
    Django中使用Celery实现异步任务队列
    使用Pyenv + pipenv来管理python版本和虚拟环境
    Django设置DEBUG=False后静态文件无法加载
    翕的来历
    Dubbo:基本原理机制
    数据库事务特性及隔离机制再到spring事务管理
    通过rocketmq思考一下mq的设计取舍
    redis的一些特性
    redis的快速机制与数据类型
    Zookeeper选举算法原理
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477103.html
Copyright © 2011-2022 走看看