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

字典序最小最小割

时间:2021-02-17 14:04:51      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:efi   namespace   amp   while   names   字典   pre   set   ==   

#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\n",tp);
		for(int i=1;i<=tp;i++)
			printf("%lld ",ss[i]);
		puts("");
	}
}

字典序最小最小割

标签:efi   namespace   amp   while   names   字典   pre   set   ==   

原文地址:https://www.cnblogs.com/ctmlpfs/p/14401012.html

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