标签:题目 ext sample logs 收入 sam 最小割 continue dfs
W 教授正在为国家航天中心计划一系列的太空飞行。每次太空飞行可进行一系列商业性实验而获取利润。现已确定了一个可供选择的实验集合E= {E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={I1,I2,…In}。实验Ej需要用到的仪器是I的子集RjÍI。配置仪器 Ik的费用为ck美元。实验Ej的赞助商已同意为该实验结果支付pj美元。W教授的任务是找出一个有效算法,确定在一次太空飞行中要进行哪些实验并因此而 配置哪些仪器才能使太空飞行的净收益最大。这里净收益是指进行实验所获得的全部收入与配置仪器的全部费用的差额。
对于给定的实验和仪器配置情况,编程找出净收益最大的试验计划。
输入格式:
第1行有2 个正整数m和n。m是实验数,n是仪器数。接下来的m 行,每行是一个实验的有关数据。第一个数赞助商同意支付该实验的费用;接着是该实验需要用到的若干仪器的编号。最后一行的n个数是配置每个仪器的费用。
输出格式:
一行是净收益。
2 3 10 1 2 25 2 3 5 6 7
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 struct Node 8 { 9 int next,to,c; 10 }edge[200001],edge2[200001]; 11 int num=1,head[1001],cur[1001],n,m,dist[1001],ans,sum,maxflow,Max; 12 void add(int u,int v,int c) 13 { 14 num++; 15 edge[num].next=head[u]; 16 head[u]=num; 17 edge[num].to=v; 18 edge[num].c=c; 19 } 20 bool get(int i) 21 { 22 char ch=getchar(); 23 while (ch==‘ ‘) ch=getchar(); 24 int x=0; 25 while (ch>=‘0‘&&ch<=‘9‘) 26 { 27 x=x*10+ch-‘0‘; 28 ch=getchar(); 29 } 30 add(i,m+x,2e9); 31 add(m+x,i,0); 32 if (ch==‘\n‘) return 0; 33 return 1; 34 } 35 bool bfs(int S,int T) 36 {int i; 37 memset(dist,-1,sizeof(dist)); 38 queue<int>Q; 39 Q.push(S); 40 dist[S]=1; 41 while (!Q.empty()) 42 { 43 int u=Q.front(); 44 Q.pop(); 45 for (i=head[u];i;i=edge[i].next) 46 { 47 int v=edge[i].to; 48 if (edge[i].c>0&&dist[v]==-1) 49 { 50 dist[v]=dist[u]+1; 51 Q.push(v); 52 } 53 } 54 } 55 if (dist[T]==-1) return 0; 56 return 1; 57 } 58 int dfs(int x,int flow,int des) 59 { 60 int res=0; 61 if (x==des) return flow; 62 for (int &i=cur[x];i;i=edge[i].next) 63 { 64 int v=edge[i].to; 65 if (dist[v]==dist[x]+1&&edge[i].c) 66 { 67 int tmp=dfs(v,min(flow-res,edge[i].c),des); 68 if (tmp<0) continue; 69 edge[i].c-=tmp; 70 edge[i^1].c+=tmp; 71 res+=tmp; 72 if (res==flow) return res; 73 } 74 } 75 return res; 76 } 77 void Dinic(int S,int T) 78 { 79 maxflow=0; 80 while (bfs(S,T)) 81 { 82 memcpy(cur,head,sizeof(cur)); 83 int a=0; 84 while (a=dfs(S,2e9,T)) maxflow+=a; 85 } 86 return; 87 } 88 int main() 89 {int i,val,S,T,j; 90 cin>>m>>n; 91 for (i=1;i<=m;i++) 92 { 93 scanf("%d",&val); 94 sum+=val; 95 add(0,i,val); 96 add(i,0,0); 97 while (get(i)); 98 } 99 for (i=1;i<=n;i++) 100 { 101 scanf("%d",&val); 102 add(m+i,m+n+1,val); 103 add(m+n+1,m+i,0); 104 } 105 S=0;T=m+n+1; 106 memcpy(edge2,edge,sizeof(edge2)); 107 Dinic(S,T); 108 ans=maxflow; 109 ans=sum-ans; 110 cout<<ans; 111 }
标签:题目 ext sample logs 收入 sam 最小割 continue dfs
原文地址:http://www.cnblogs.com/Y-E-T-I/p/7755485.html