...................................................................................
说起这道题,我的唯一感受是:该死,TM卡常.
这卡常卡的我不要不要的,反正我最后没卡过去.
.....................................................愤怒的分割线..............
这道题的主要思路是求字典序最小的最小割,做完最小割后,按照贪心原则选取,每选中一条边,那么做T->V和U->S的最大流,消除这条边的影响.
代码感觉在什么地方死循环了,一直TLE,但并没有什么发现.
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> #include<queue> #include<set> #include<map> #include<iomanip> using namespace std; #define ll long long #define db double #define up(i,j,n) for(int i=j;i<=n;i++) #define pii pair<int,int> #define uint unsigned int #define FILE "dealing" #define eps 1e-4 int read(){ int x=0,f=1,ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return x*f; } template<class T> bool cmax(T& a,T b){return a<b?a=b,true:false;} template<class T> bool cmin(T& a,T b){return a>b?a=b,true:false;} const int maxn=100550,limit=50100,inf=(int)(2e9),mod=(int)1e9+7; int n; int a[maxn],b[maxn],c[maxn]; namespace dinic{ struct node{ int y,next,rev;int flow; }e[maxn<<1];int len,linkk[maxn]; void insert(int x,int y,int flow){ e[++len].y=y; e[len].next=linkk[x]; linkk[x]=len; e[len].flow=flow; e[len].rev=len+1; e[++len].y=x; e[len].next=linkk[y]; linkk[y]=len; e[len].flow=0; e[len].rev=len-1; } int S,T,SS,TT,q[maxn],d[maxn],head,tail; bool makelevel(){ head=tail=0; up(i,0,n*2+2)d[i]=-1; d[S]=0;q[++tail]=S; while(++head<=tail){ int x=q[head]; for(int i=linkk[x];i;i=e[i].next) if(d[e[i].y]==-1&&e[i].flow)d[e[i].y]=d[x]+1,q[++tail]=e[i].y; } return d[T]!=-1; } int makeflow(int x,int flow){ if(x==T||!flow)return flow; int maxflow=0,dis; for(int i=linkk[x];i&&maxflow<flow;i=e[i].next){ if(e[i].flow&&d[e[i].y]==d[x]+1) if(dis=makeflow(e[i].y,min(e[i].flow,flow-maxflow))){ e[i].flow-=dis; e[e[i].rev].flow+=dis; maxflow+=dis; } } if(!maxflow)d[x]=-1; return maxflow; } int dinic(){ int ans=0,d; while(makelevel()) while(d=makeflow(S,inf)) ans+=d; return ans; } int f[maxn],Max; pii k[maxn]; void prepare(){ up(i,0,n*2+2)linkk[i]=f[i]=0; len=0; } void makeedge(){ prepare(); Max=0;SS=S=n*2+1,TT=T=S+1; up(i,1,n)insert(i*2-1,i*2,b[i]); up(i,1,n)up(j,0,i-1)if(a[i]>a[j])cmax(f[i],f[j]+1); up(i,1,n)up(j,i+1,n)if(a[j]>a[i]&&f[j]==f[i]+1)insert(i*2,j*2-1,inf); up(i,1,n)cmax(Max,f[i]); up(i,1,n){ if(Max==f[i])insert(i*2,T,inf); if(f[i]==1)insert(S,i*2-1,inf); } } int po[maxn],cnt=0; void solve(){ up(i,1,n)k[i].first=c[i],k[i].second=i; sort(k+1,k+n+1);cnt=0; int ans=dinic(); up(i,1,n){ int x=k[i].second; S=x*2-1,T=x*2; if(!makelevel()){ po[++cnt]=x; S=TT,T=x*2; dinic(); S=x*2-1,T=SS; dinic(); e[x*2].flow=0; } } printf("%d %d ",ans,cnt); sort(po+1,po+cnt+1); up(i,1,cnt)printf("%d%c",po[i],i==cnt?' ':' '); } }; int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); int T; scanf("%d",&T); while(T--){ scanf("%d",&n); up(i,1,n)scanf("%d",&a[i]); up(i,1,n)scanf("%d",&b[i]); up(i,1,n)scanf("%d",&c[i]); dinic::makeedge(); dinic::solve(); } //cout<<clock()<<endl; return 0; }