HDU 4971 A simple brute force problem.最大权闭合图

来源:互联网 发布:编程模块化设计的优点 编辑:程序博客网 时间:2024/05/09 01:07

题意:这里有n个项目和m个技术问题,只有完成技术问题才能完成项目,实现技术问题是有花费的,而完成一个项目是有利润的。题目告诉我们哪些技术问题是用来解决指定问题的。然后有一些限制条件,就是在完成技术问题i前,需要解决技术问题j,问你利润最大值。


想法:很裸的最大权闭图。

1.虚拟source,sink

2.source到盈利点连一条容量为盈利值的边

3.亏损点到sink连一条容量为亏损只的边

4.亏损点直接的先后关系建边,容量为inf


#include<iostream>#include<cstring>#include<cstdio>#include<queue>#define inf 0x7fffffff using namespace std;const int nodes=80;const int edges=10000;int n,m;int s,t;struct node{int v,flow,next;}e[edges];int head[nodes],cur[nodes],cnt;class Dinic{public:int spath(){queue<int>q;while(!q.empty()) q.pop();memset(dis,-1,sizeof(dis));dis[s]=0;q.push(s);while(!q.empty()){int u=q.front();q.pop();for(int i=head[u];i+1;i=e[i].next){int v=e[i].v;if(dis[v]==-1&&e[i].flow>0){dis[v]=dis[u]+1;q.push(v);}}}return dis[t]!=-1;}int Min(int a,int b){if(a<b) return a;return b;}int dfs(int u,int flow){int cost=0;if(u==t) return flow;for(int i=head[u];i+1;i=e[i].next){int v=e[i].v;if(dis[v]==dis[u]+1&&e[i].flow>0){int min=dfs(v,Min(e[i].flow,flow-cost));if(min>0) {e[i].flow-=min;e[i^1].flow+=min;cost+=min;if(cost==flow) break;}else dis[v]=-1;}}return cost;}int result(){int res=0;while(spath()){res+=dfs(s,inf);}return res;}private:int dis[nodes];}dinic;void Init(){memset(head,-1,sizeof(head));cnt=0;}void add(int a,int b,int c){e[cnt].v=b;e[cnt].flow=c;e[cnt].next=head[a];head[a]=cnt++;e[cnt].v=a;e[cnt].flow=0;e[cnt].next=head[b];head[b]=cnt++;}int main(){int num,ca=1;scanf("%d",&num);while(num--){Init();int sum=0;scanf("%d%d",&n,&m);s=0;t=n+m+1;for(int i=1;i<=n;i++){int a;scanf("%d",&a);sum+=a;add(s,i,a);}for(int i=1;i<=m;i++){int a;scanf("%d",&a);add(i+n,t,a);}for(int i=1;i<=n;i++){int k;scanf("%d",&k);while(k--){int a;scanf("%d",&a);a++;add(i,a+n,inf);}}for(int i=1;i<=m;i++){for(int j=1;j<=m;j++){int a;scanf("%d",&a);if(a) add(i+n,j+n,inf);}}printf("Case #%d: ",ca++);printf("%d\n",sum-dinic.result());}return 0;}

0 0