题目连接:https://loj.ac/problem/6001
W 教授正在为国家航天中心计划一系列的太空飞行。每次太空飞行可进行一系列商业性实验而获取利润。现已确定了一个可供选择的实验集合 E={E1,E2,⋯,Em} E = \{ E_1, E_2, \cdots, E_m \} E={E1,E2,⋯,Em},和进行这些实验需要使用的全部仪器的集合 I={I1,I2,⋯,In} I = \{ I_1, I_2, \cdots, I_n \} I={I1,I2,⋯,In}。实验 Ej E_j Ej 需要用到的仪器是 I I I 的子集 Rj⊆I R_j \subseteq I Rj⊆I。
配置仪器 Ik I_k Ik 的费用为 ck c_k ck 美元。实验 Ej E_j Ej 的赞助商已同意为该实验结果支付 pj p_j pj 美元。W 教授的任务是找出一个有效算法,确定在一次太空飞行中要进行哪些实验并因此而配置哪些仪器才能使太空飞行的净收益最大。这里净收益是指进行实验所获得的全部收入与配置仪器的全部费用的差额。
对于给定的实验和仪器配置情况,编程找出净收益最大的试验计划。
输入格式
第 1 1 1 行有 2 2 2 个正整数 m m m 和 n n n。m m m 是实验数,n n n 是仪器数。接下来的 m m m 行,每行是一个实验的有关数据。第一个数赞助商同意支付该实验的费用;接着是该实验需要用到的若干仪器的编号。最后一行的 n n n 个数是配置每个仪器的费用。
输出格式
第 1 1 1 行是实验编号,第 2 2 2 行是仪器编号,最后一行是净收益。
样例
样例输入
2 3
10 1 2
25 2 3
5 6 7
样例输出
1 2
1 2 3
17
最大闭合集:http://www.cnblogs.com/liyinggang/p/5553665.html
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int maxn = 250;
const int inf = 1e9 + 1e9;
typedef long long ll;
struct Edge
{
int fr,to,cap,flow,nex;
};
struct Dinic
{
int n,m,s,t;
Edge edges[11005];
bool vis[maxn+5];
int d[maxn+5],head[maxn+5];
void Init()
{
m = 0;
memset(head,-1,sizeof(head));
}
void Addedge(int fr,int to,int cap)
{
edges[m] = (Edge){fr,to,cap,0,head[fr]}, head[fr] = m++;
edges[m] = (Edge){to,fr,0,0,head[to]}, head[to] = m++;
}
bool BFS()
{
memset(vis,0,sizeof(vis));
queue<int>Q;
Q.push(s);
d[s] = 0, vis[s] = 1;
while(!Q.empty())
{
int x = Q.front();
Q.pop();
for(int i=head[x]; i!=-1 ; i=edges[i].nex)
{
Edge &e = edges[i];
if(!vis[e.to]&&e.cap>e.flow)
{
vis[e.to] = 1;
d[e.to] = d[x] + 1;
Q.push(e.to);
}
}
}
return vis[t];
}
int DFS(int x,int a)
{
if(x==t||a==0) return a;
int flow = 0,f;
for(int i=head[x]; i!=-1 ; i=edges[i].nex)
{
Edge &e = edges[i];
if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
{
e.flow+=f;
edges[i^1].flow -=f;
flow+=f;
a-=f;
if(a==0) break;
}
}
return flow;
}
int Maxflow(int s,int t)
{
this->s = s, this->t = t;
int flow = 0;
while(BFS())
{
flow+=DFS(s,inf);
}
return flow;
}
} my;
int n,m,s,t;
int main()
{
int val,u,cot=0;
scanf("%d %d",&m,&n);
s = 0, t = n+m+1;
my.Init();
for(int i=1; i<=m; i++)
{
scanf("%d",&val);
cot+=val;
my.Addedge(s,i,val);
while(getchar()!='\n')
{
scanf("%d",&u);
my.Addedge(i,u+m,inf);
}
}
for(int i=1; i<=n; i++)
{
scanf("%d",&val);
my.Addedge(i+m,t,val);
}
int cost = cot - my.Maxflow(s,t);
for(int i=1; i<=m; i++)
{
if(!my.vis[i]) continue;
printf("%d ",i);
}
printf("\n");
for(int i=1; i<=n; i++)
{
if(!my.vis[i+m]) continue;
printf("%d ",i);
}
printf("\n%d\n",cost);
return 0;
}