Address: HDU 4971
During the competition, the maximum privilege was not closed. At that time, I also discussed the cost stream and DP with my teammates for a long time .. Now it seems to be the biggest right to close the water question...
Idea of creating a graph: the source node connects to the project, the weight is the profit, the sink node connects to the technology project, the weight is the cost, and then the dependent connection has a directed edge. Using the positive weight and minus the minimum cut is the answer.
#include <iostream>#include <cstdio>#include <string>#include <cstring>#include <stdlib.h>#include <math.h>#include <ctype.h>#include <queue>#include <map>#include <set>#include <algorithm>using namespace std;const int INF=0x3f3f3f3f;int head[3000], cnt, source, sink, nv;int d[3000], num[3000], pre[3000], cur[3000];struct node{ int u, v, next; int cap;} edge[1000000];void add(int u, int v, int cap){ edge[cnt].v=v; edge[cnt].cap=cap; edge[cnt].next=head[u]; head[u]=cnt++; edge[cnt].v=u; edge[cnt].cap=0; edge[cnt].next=head[v]; head[v]=cnt++;}void bfs(){ memset(d,-1,sizeof(d)); memset(num,0,sizeof(num)); queue<int>q; q.push(sink); d[sink]=0; num[0]=1; while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(d[v]==-1) { d[v]=d[u]+1; num[d[v]]++; q.push(v); } } }}int isap(){ memcpy(cur,head,sizeof(cur)); int u=pre[source]=source, i, flow=0; bfs(); while(d[source]<nv) { if(u==sink) { int f=INF, pos; for(i=source; i!=sink; i=edge[cur[i]].v) { if(f>edge[cur[i]].cap) { f=edge[cur[i]].cap; pos=i; } } for(i=source; i!=sink; i=edge[cur[i]].v) { edge[cur[i]].cap-=f; edge[cur[i]^1].cap+=f; } flow+=f; u=pos; } for(i=cur[u]; i!=-1; i=edge[i].next) { if(d[edge[i].v]+1==d[u]&&edge[i].cap) { break; } } if(i!=-1) { cur[u]=i; pre[edge[i].v]=u; u=edge[i].v; } else { if(--num[d[u]]==0) break; int mind=nv; for(i=head[u]; i!=-1; i=edge[i].next) { if(mind>d[edge[i].v]&&edge[i].cap) { mind=d[edge[i].v]; cur[u]=i; } } d[u]=mind+1; num[d[u]]++; u=pre[u]; } } return flow;}int main(){ int t, n, m, x, num=0, k, i, j, sum; scanf("%d",&t); while(t--) { num++; scanf("%d%d",&n,&m); memset(head,-1,sizeof(head)); cnt=0; source=0; sink=n+m+1; nv=sink+1; sum=0; for(i=1;i<=n;i++) { scanf("%d",&x); add(source,i,x); sum+=x; } for(i=1;i<=m;i++) { scanf("%d",&x); add(i+n,sink,x); } for(i=1;i<=n;i++) { scanf("%d",&k); while(k--) { scanf("%d",&x); add(i,x+n+1,INF); } } for(i=1;i<=m;i++) { for(j=1;j<=m;j++) { scanf("%d",&x); if(x) add(i+n,j+n,INF); } } printf("Case #%d: ",num); int ans=isap(); printf("%d\n",sum-ans); } return 0;}
HDU 4971 a simple brute force problem. (Minimum Cut-max weight closed)