Discription
SmallR is a biologist. Her latest research finding is how to change the sex of dogs. In other words, she can change female dogs into male dogs and vice versa.
She is going to demonstrate this technique. Now SmallR has n dogs, the costs of each dog's change may be different. The dogs are numbered from 1 to n. The cost of change for dog i is vi RMB. By the way, this technique needs a kind of medicine which can be valid for only one day. So the experiment should be taken in one day and each dog can be changed at most once.
This experiment has aroused extensive attention from all sectors of society. There are m rich folks which are suspicious of this experiment. They all want to bet with SmallR forcibly. If SmallR succeeds, the i-th rich folk will pay SmallR wi RMB. But it's strange that they have a special method to determine whether SmallR succeeds. For i-th rich folk, in advance, he will appoint certain ki dogs and certain one gender. He will think SmallR succeeds if and only if on some day the ki appointed dogs are all of the appointed gender. Otherwise, he will think SmallR fails.
If SmallR can't satisfy some folk that isn't her friend, she need not pay him, but if someone she can't satisfy is her good friend, she must pay g RMB to him as apologies for her fail.
Then, SmallR hope to acquire money as much as possible by this experiment. Please figure out the maximum money SmallR can acquire. By the way, it is possible that she can't obtain any money, even will lose money. Then, please give out the minimum money she should lose.
Input
The first line contains three integers n, m, g (1 ≤ n ≤ 104, 0 ≤ m ≤ 2000, 0 ≤ g ≤ 104). The second line contains n integers, each is 0 or 1, the sex of each dog, 0 represent the female and 1 represent the male. The third line contains n integers v1, v2, ..., vn (0 ≤ vi ≤ 104).
Each of the next m lines describes a rich folk. On the i-th line the first number is the appointed sex of i-th folk (0 or 1), the next two integers are wi and ki (0 ≤ wi ≤ 104, 1 ≤ ki ≤ 10), next ki distinct integers are the indexes of appointed dogs (each index is between 1 and n). The last number of this line represents whether i-th folk is SmallR's good friend (0 — no or 1 — yes).
Output
Print a single integer, the maximum money SmallR can gain. Note that the integer is negative if SmallR will lose money.
Example
5 5 9
0 1 1 1 0
1 8 6 2 3
0 7 3 3 2 1 1
1 8 1 5 1
1 0 3 2 1 4 1
0 8 3 4 2 1 0
1 7 2 4 1 1
2
5 5 8
1 0 1 1 1
6 5 4 2 8
0 6 3 2 3 4 0
0 8 3 3 2 4 0
0 0 3 3 4 1 1
0 10 3 4 3 1 1
0 4 3 3 4 1 1
16
题目大意就是有N个点,每个点一开始是黑色或者白色,把i点的颜色翻转需要v[i]的代价。
同时还有M个计划,每个计划要求计划内的点全黑或者全白,如果满足会得到l[i]的收益,
但是如果这个计划是朋友的而且没有被满足的话是需要付出g的代价的,其中g是题目中给定的常数。
求最大收益。
这是一个经典的最大权闭合子图的集合划分问题。
首先我们要把答案设置成所有可能得到的收益,然后再减去最少可能付出的代价。
而求这个最少可能付出的代价就是一个网络流的最小割问题。
本题中,我们把每个白点连S,黑点连T,容量为v[i],代表转换颜色的代价。
类似的,把每个白计划连S,黑计划连T,容量为l[i]+(该计划是否是朋友的?g:0),
代表舍弃这个计划的代价。
对于每个计划,如果计划中的一个节点的初始颜色和计划要求的颜色不一样,
那么把计划和该点连边,容量为inf,表示要么舍弃这个计划,要么让计划涉及的
异色节点全部翻转。
光这样还不行,因为可能一个点在某个计划中翻转了,而在另一个计划中不需要翻转。
所以我们最后需要把有冲突的计划连边,容量为inf,表示这两个计划不能同时选择。
然后就可以直接求解了。
#12389581 | JYYHH's solution for [CodeForces-311E] Status Time Memory Length Lang Accepted 31ms 13256kB 2226 GNU G++ 5.1.0 Submitted 2018-01-25 11:24:36 Shared #include<iostream> #include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> #include<vector> #include<queue> #include<cmath> #define ll long long #define pb push_back #define maxn 20005 using namespace std; const int inf=1<<29; vector<int> g[maxn]; struct lines{ int to,flow,cap; }l[maxn*41]; int n,m,G,S,T,t=-1,cur[maxn]; int d[maxn],kk,val; bool v[maxn]; inline void add(int xx,int yy,int zz){ l[++t]=(lines){yy,0,zz},g[xx].pb(t); l[++t]=(lines){xx,0,0},g[yy].pb(t); } inline bool bfs(){ queue<int> q; memset(v,0,sizeof(v)); d[S]=0,v[S]=1,q.push(S); int x; lines e; while(!q.empty()){ x=q.front(),q.pop(); for(int i=g[x].size()-1;i>=0;i--){ e=l[g[x][i]]; if(!v[e.to]&&e.flow<e.cap){ d[e.to]=d[x]+1; v[e.to]=1; q.push(e.to); } } } return v[T]; } int dfs(int x,int a){ if(x==T||!a) return a; int flow=0,f,sz=g[x].size(); for(int &i=cur[x];i<sz;i++){ lines &e=l[g[x][i]]; if(d[x]==d[e.to]-1&&(f=dfs(e.to,min(a,e.cap-e.flow)))){ flow+=f,a-=f; e.flow+=f,l[g[x][i]^1].flow-=f; if(!a) break; } } return flow; } inline int max_flow(){ int an=0; while(bfs()){ memset(cur,0,sizeof(cur)); an+=dfs(S,inf); } return an; } int tp[maxn],now,opt[maxn]; int tot,pos,ooOOooOOoo; vector<int> bel[maxn]; int main(){ scanf("%d%d%d",&n,&m,&G); S=0,T=n+m+1; for(int i=1;i<=n;i++) scanf("%d",tp+i); for(int i=1;i<=n;i++){ scanf("%d",&now); //白点连S,黑点连T,容量含义为转变颜色的代价 if(tp[i]) add(i,T,now); else add(S,i,now); } for(int i=1;i<=m;i++){ scanf("%d%d%d",opt+i,&val,&kk); while(kk--){ scanf("%d",&pos); if(opt[i]^tp[pos]){ //白计划连黑点,白点连黑计划,不能同时选择 if(opt[i]) add(pos,n+i,inf); else add(n+i,pos,inf); } bel[pos].pb(i); } //白计划连S,黑计划连T,容量含义为该计划不被满足的代价(g+val) tot+=val,scanf("%d",&ooOOooOOoo); if(ooOOooOOoo) val+=G; if(opt[i]) add(n+i,T,val); else add(S,n+i,val); } //注意涉及同一个点的白计划和黑计划也不能共存 for(int i=1;i<=n;i++){ int sz=bel[i].size(),to1,to2; for(int j=0;j<sz;j++){ to1=bel[i][j]; for(int u=j+1;u<sz;u++){ to2=bel[i][u]; if(opt[to1]^opt[to2]){ if(opt[to1]) add(to2+n,to1+n,inf); else add(to1+n,to2+n,inf); } } } } cout<<tot-max_flow()<<endl; return 0; }