• 字典序最小最小割


    #include<bits/stdc++.h>
    #define N 300010
    using namespace std;
    #define int long long
    int h[N],nxt[N],v[N],w[N],s,t,dep[N],ec,p[N],n,a[N],b[N],c[N],f[N],v1[N],v2[N],ss[N];
    void add(int a,int b,int c){v[++ec]=b;w[ec]=c;nxt[ec]=h[a];h[a]=ec;}
    void adj(int a,int b,int c){add(a,b,c);add(b,a,0);}
    struct no{
    	int a,b,x,y,id;
    }st[N];
    int operator <(no x,no y){
    	return x.a<y.a;
    } 
    bool bfs(){
        queue<int>q;
    	q.push(s);
    	for(int i=0;i<=2*n+3;i++)
    		dep[i]=0;
    	dep[s]=1;
        while(!q.empty()){
            int x=q.front();
    		q.pop();
            for(int i=h[x];i;i=nxt[i])
                if(w[i]&&!dep[v[i]]){
                	dep[v[i]]=dep[x]+1;
    				q.push(v[i]);
    			}
        }
    	return dep[t];
    }
    int dfs(int x,int dis){
        if(x==t)
    		return dis;
    	int tp=dis;
        for(int i=h[x];i;i=nxt[i])
            if(dep[v[i]]==dep[x]+1&&w[i]){
                int f=dfs(v[i],min(tp,w[i]));
                if(!f)
                	dep[v[i]]=0;
                tp-=f;
                w[i]-=f;
    			w[i^1]+=f;
    			if(!tp)
    				break;
            }
    	return dis-tp;
    }
    int din(){
        int aans=0;
        while(bfs())
    		aans+=dfs(s,1e9);
        return aans;
    }
    int fd(int x,int y){
    	for(int i=0;i<=2*n+3;i++)
    		dep[i]=0;
    	queue<int>q;
    	q.push(x);
    	while(!q.empty()){
    		int x=q.front();
    		q.pop();
    		if(dep[x])
    			continue;
    		dep[x]=1;
    		for(int i=h[x];i;i=nxt[i])
    			if(w[i]&&!dep[v[i]])
    				q.push(v[i]);
    	}
    	return dep[y];
    }
    signed main(){
    	int T;
    	scanf("%lld",&T);
    	while(T--){
    		memset(h,0,sizeof(h));
    		ec=1;
    		memset(f,0,sizeof(f));
    		scanf("%lld",&n);
    		for(int i=1;i<=n;i++)
    			scanf("%lld",&a[i]);
    		for(int i=1;i<=n;i++)
    			scanf("%lld",&b[i]);
    		for(int i=1;i<=n;i++)
    			scanf("%lld",&c[i]);
    		for(int i=1;i<=n;i++)
    			f[i]=1;
    		for(int i=2;i<=n;i++)
    			for(int j=1;j<i;j++)
    				if(a[i]>a[j])
    					f[i]=max(f[i],f[j]+1);
    		int va=0;
    		for(int i=1;i<=n;i++)
    			va=max(va,f[i]);
    		s=0;
    		int ct=0;
    		for(int i=1;i<=n;i++)
    			v1[i]=++ct;
    		for(int i=1;i<=n;i++)
    			v2[i]=++ct;
    		for(int i=1;i<=n;i++){
    			adj(v1[i],v2[i],b[i]);
    			st[i]=(no){c[i],i,v1[i],v2[i],ec-1};
    		}
    		sort(st+1,st+n+1);
    		t=ct+1;
    		for(int i=1;i<=n;i++)
    			if(f[i]==1)
    				adj(s,v1[i],1e9);
    		for(int i=1;i<=n;i++)
    			if(f[i]==va)
    				adj(v2[i],t,1e9);
    		for(int i=2;i<=n;i++)
    			for(int j=1;j<i;j++)
    				if(a[i]>a[j]&&f[j]+1==f[i])
    					adj(v2[j],v1[i],1e9);
    		printf("%lld ",din());
    		int tp=0;
    		for(int i=1;i<=n;i++){
    			int a=st[i].x,b=st[i].y,c=st[i].id;
    			if(fd(a,b))
    				continue;
    			s=a;
    			t=0;
    			din();
    			s=ct+1;
    			t=b;
    			din();
    			w[c]=w[c+1]=0;
    			ss[++tp]=st[i].b;
    		}
    		sort(ss+1,ss+tp+1);
    		printf("%lld
    ",tp);
    		for(int i=1;i<=tp;i++)
    			printf("%lld ",ss[i]);
    		puts("");
    	}
    }
    
  • 相关阅读:
    ubuntu升级显卡驱动
    __slots__属性,声明实力属性名字列表
    isinstance 与 type 的区别
    conda使用技巧
    卷积神经网络参数
    apache nginx php不显示版本号
    30个实用的Linux find命令示例
    账号的管理的那点事
    Linux 命令整理 —— 基本操作
    Linux 命令整理 —— 用户管理
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14401012.html
Copyright © 2020-2023  润新知