Wiki 1233(太空飞行计划问题-最大权闭合子图)

来源:互联网 发布:图片美化软件 编辑:程序博客网 时间:2024/04/28 16:31

W 教授正在为国家航天中心计划一系列的太空飞行。每次太空飞行可进行一系列商业性实验而获取利润。现已确定了一个可供选择的实验集合 E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合 I={I1, I2,… I n } 。实验 Ej需要用到的仪器是 I 的子集 Rj˝I。配置仪器 Ik的费用为 ck美元。实验 Ej的赞助商已同意为该实验结果支付 pj美元。W 教授的任务是找出一个有效算法,确定在一次太空飞行中要进行哪些实验并因此而配置哪些仪器才能使太空飞行的净收益最大。这里净收益是指进行实验所获得的全部收入与配置仪器的全部费用的差额。  

对于给定的实验和仪器配置情况,编程找出净收益最大的试验计划。

第 1 行有 2 个正整数 m和 n。m 是实验数,n 是仪器数。接下来的 m 行,每行是一个实验的有关数据。第一个数赞助商同意支付该实验的费用;接着是该实验需要用到的若干仪器的编号。最后一行的 n 个数是配置每个仪器的费用。

第 1 行是实验编号;第 2行是仪器编号;最后一行是净收益。

2 3

10 1 2

25 2 3

5 6 7

1 2  

1 2 3 

17

最大权闭合子图,入门题。

把S向正费用点连边,T向负费用点连边,原图的边间连+oo

然后做最小割=min(未选收益+选花费)


答案=选收益-选花费=全选收益-(未选收益+选花费)


#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<functional>#include<cmath>#include<cctype>#include<cassert>#include<climits>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define ForD(i,n) for(int i=n;i;i--)#define Forp(x) for(int p=pre[x];p;p=next[p])#define RepD(i,n) for(int i=n;i>=0;i--)#define MEM(a) memset(a,0,sizeof(a))#define MEMI(a) memset(a,127,sizeof(a))#define MEMi(a) memset(a,128,sizeof(a))#define INF (2139062143)#define F (1000000009)#define MAXN (1000000)#define MAXM (1000000)typedef long long ll;int edge[MAXM],pre[MAXN]={0},next[MAXM]={0},weight[MAXM],size=1;void addedge(int u,int v,int w){   edge[++size]=v;   weight[size]=w;   next[size]=pre[u];   pre[u]=size;}void addedge2(int u,int v,int w){addedge(u,v,w),addedge(v,u,0);}int n1,n2,s,t,n;int d[MAXN]={0},cnt[MAXN]={0};int sap(int x,int flow){   if (x==t) return flow;   int nowflow=0;   Forp(x)   {      int &v=edge[p];      if (d[x]-1==d[v]&&weight[p]>0)       {         int fl=sap(v,min(weight[p],flow));         nowflow+=fl,flow-=fl,weight[p]-=fl,weight[p^1]+=fl;         if (!flow) return nowflow;      }         }   if (!(--cnt[d[x]++])) d[s]=n+1;   cnt[d[x]]++;    return nowflow;}int label[MAXN]={0};void dfs(int x){   label[x]=1;   Forp(x)   {      int &v=edge[p];      if (weight[p]>0&&!label[v]) dfs(v);   }}int t1[MAXN],t2[MAXN];int main(){   //freopen("wiki1233.in","r",stdin);   scanf("%d%d",&n1,&n2); //n1:expr  n2:mechine   n=n1+n2+2;s=n-1,t=n;   int total=0;   For(i,n1)   {      int w;      scanf("%d",&w);addedge2(s,i,w);t1[i]=size-1;       total+=w;      //cout<<w<<' ';      char c;      while (c=getchar())      {         if (c=='\n') break;         else if (isdigit(c))         {            int a;            ungetc(c,stdin);scanf("%d",&a);            addedge2(i,n1+a,INF);         }              }         }//cout<<endl;   For(i,n2)    {      int w;      scanf("%d",&w);addedge2(n1+i,t,w);t2[i]=size-1;t2[i]=size-1;         }      int ans=0;cnt[0]=n;   while (d[s]<=n) ans+=sap(s,INF);         dfs(s);      //For(i,n) if (label[i]) cout<<i<<' ';cout<<endl;      For(i,n1) if (label[i]^label[s]==0) cout<<i<<' ';cout<<endl;   For(i,n2) if (label[n1+i]^label[t]) cout<<i<<' ';cout<<endl;      /*   bool b=0;   For(i,n1) cout<<weight[t1[i]]<<' ';cout<<endl;   For(i,n1) if (weight[t1[i]^1]==0)    {      if (b) printf(" ");b=1;      printf("%d",i);   } puts("");      b=0;   For(i,n2) if (weight[t2[i]]==0)    {      if (b) printf(" ");b=1;      printf("%d",i);   } puts("");   */            cout<<total-ans<<endl;      //while (1);   return 0;}





原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 狗狗嘴巴被大狗咬肿了怎么办 花了钱心里难受怎么办 狗在屋里有味道怎么办 养狗家里有异味怎么办 养狗房子有味道怎么办 狗身上有腥臭味怎么办 狗狗不想养了怎么办 药流2天后没出血怎么办 药流当天血多怎么办 怀孕四十天不想要怎么办 人流后出血量大怎么办 药流一直不出血怎么办 药流一直不见红怎么办 药流12天还流血怎么办? 把别人车刮了怎么办 车划掉漆了怎么办啊 倒车时碰了车怎么办 车头掉了一点漆怎么办 新买的车被刮了怎么办 白色车车头漆掉了一小块怎么办 临时牌照丢了1张怎么办 临牌遗失了一张怎么办 临牌只有一张了怎么办 临时牌丢了一个怎么办 药流出血特别多怎么办 新车刮擦了一点怎么办 自己的车撞墙了怎么办 新车被撞了个坑怎么办 车门被刮变形了怎么办 撞到别人的新车怎么办 新车掉了一点漆怎么办 新车擦了点漆怎么办 车挂了一点漆怎么办 第一天上班中途想走了怎么办 车子前脸裂开了怎么办 不想干了想辞职怎么办 药流期间老是吐怎么办 在工厂上班辞工后没发工资怎么办 培训期三天想走怎么办 药流吃了药吐了怎么办 工作3天不下去怎么办