(其实主要并不是写题解,只是记录一下网络流的一些……结论?)
1.「边u->v处于割集中」<=>「跑完最大流的残量网络上,u->v无路径」
(敲黑板划重点,不是u->v这条边为空就完事了,WA了好几次......)
(写网络流总是忘记反向边影响的我🤦♀️)
2.「割去割集中的u->v再跑网络流」即「跑T->v,u->S的最大流」
(考虑把v->u这条边变回u->v,再将其流量清空。)
总之,知道这两点这题就差不多了。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define rep(i,l,r) for(int i=l;i<=r;++i) 5 #define per(i,r,l) for(int i=r;i>=l;--i) 6 #define pb push_back 7 #define mp make_pair 8 9 typedef long long ll; 10 typedef pair<int,int> pii; 11 12 const int NN=707,N=1e5+3,M=1e6+3; 13 const ll INF=1e13; 14 15 int n,a[NN],b[NN],c[NN]; 16 17 int fst[N],nxt[M],to[M],len,S,T; 18 ll f[M]; 19 void ad(int u,int v,ll w){ 20 to[++len]=v;f[len]=w; 21 nxt[len]=fst[u];fst[u]=len; 22 } 23 void add(int u,int v,ll w){ 24 ad(u,v,w); 25 ad(v,u,0); 26 } 27 28 int bg,ed,oc[N],dep[N]; 29 queue<int>q; 30 bool bfs(){ 31 rep(i,S,T){ 32 dep[i]=0; 33 oc[i]=fst[i]; 34 } 35 while(!q.empty()) q.pop(); 36 37 dep[bg]=1;q.push(bg); 38 while(!q.empty()){ 39 int fa=q.front();q.pop(); 40 for(int i=fst[fa];i;i=nxt[i]){ 41 int son=to[i]; 42 if(dep[son]==0&&f[i]>0){ 43 dep[son]=dep[fa]+1; 44 q.push(son); 45 46 if(son==ed) return 1; 47 } 48 } 49 } 50 51 return 0; 52 } 53 ll dfs(int fa,ll fl){ 54 if(fa==ed||fl==0) return fl; 55 56 ll ans=0,F; 57 for(int &i=oc[fa];i;i=nxt[i]){ 58 int son=to[i]; 59 if(dep[son]==dep[fa]+1&&f[i]>0){ 60 F=dfs(son,min(fl,f[i])); 61 62 fl-=F;f[i]-=F; 63 ans+=F;f[i^1]+=F; 64 65 if(fl==0) break; 66 } 67 } 68 69 return ans; 70 } 71 ll fl(int B,int E,ll Inf){ 72 bg=B;ed=E; 73 74 ll ans=0,F; 75 while(bfs()) while(F=dfs(bg,Inf)) ans+=F; 76 return ans; 77 } 78 79 80 int main(){ 81 int cs; 82 scanf("%d",&cs); 83 while(cs--){ 84 scanf("%d",&n); 85 rep(i,1,n) scanf("%d",&a[i]); 86 rep(i,1,n) scanf("%d",&b[i]); 87 rep(i,1,n) scanf("%d",&c[i]); 88 89 //init 90 S=1;T=(n+1)<<1;len=1; 91 rep(i,S,T) fst[i]=0; 92 rep(i,1,n) add(i<<1,i<<1|1,b[i]); 93 94 int l[NN],mx=0; 95 rep(i,1,n){ 96 l[i]=1; 97 rep(j,1,i-1) 98 if(a[j]<a[i]) l[i]=max(l[i]-1,l[j])+1; 99 rep(j,1,i-1) 100 if(a[j]<a[i]&&l[j]+1==l[i]) 101 add(j<<1|1,i<<1,INF); 102 103 if(l[i]==1) add(S,i<<1,INF); 104 mx=max(mx,l[i]); 105 } 106 rep(i,1,n) 107 if(l[i]==mx) add(i<<1|1,T,INF); 108 109 110 vector<pii> pr; 111 pr.clear(); 112 rep(i,1,n) pr.pb(mp(c[i],i)); 113 sort(pr.begin(),pr.end()); 114 115 116 printf("%lld ",fl(S,T,INF)); 117 vector<int> ans; 118 ans.clear(); 119 120 rep(i,0,n-1){ 121 int no=pr[i].second; 122 bg=no<<1;ed=no<<1|1; 123 124 if(bfs()) continue; 125 126 ans.pb(no); 127 fl(T,no<<1|1,b[no]); 128 fl(no<<1,S,b[no]); 129 f[no<<1]=f[no<<1|1]=0; 130 } 131 132 sort(ans.begin(), ans.end()); 133 printf("%d\n",(int)ans.size()); 134 rep(i,0,(int)ans.size()-1) 135 printf("%d ",ans[i]); 136 printf("\n"); 137 } 138 }
日常写错……欢迎指正
QQ:2960005671
邮箱:bleavescoder@163.com