【问题描述】
W 教授正在为国家航天中心计划一系列的太空飞行。每次太空飞行可进行一系列商业性实验而获取利润。现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={ I1, I2,…,In }。实验Ej 需要用到的仪器是I的子集Rj∈I。配置仪器Ik 的费用为ck 美元。实验Ej 的赞助商已同意为该实验结果支付pj 美元。W教授的任务是找出一个有效算法,确定在一次太空飞行中要进行哪些实验并因此而配置哪些仪器才能使太空飞行的净收益最大。这里净收益是指进行实验所获得的全部收入与配置仪器的全部费用的差额。
【编程任务】
对于给定的实验和仪器配置情况,编程找出净收益最大的试验计划。
【数据输入】
第1行有2个正整数m和n(m,n <= 100)。m是实验数,n是仪器数。接下来的m行,每行是一个实验的有关数据。第一个数赞助商同意支付该实验的费用;接着是该实验需要用到的若干仪器的编号。最后一行的n个数是配置每个仪器的费用。
【结果输出】
第1行是实验编号;第2行是仪器编号;最后一行是净收益。
【输入文件示例】shuttle.in
2 3
10 1 2
25 2 3
5 6 7
【输出文件示例】shuttle.out
1 2
1 2 3
17
图论 网络流 特别的读入技巧
题目本身就是个裸的最大权闭合子图,没什么好说的
但是这个输入数据很好玩啊,每行没有终止标记。
但是读入也没什么难的,把读入优化魔改了一下就可以直接用了。
交上去发现还是T了,下回来数据发现——数据文件前两行有两个换行符,然后才是m和n,于是17行那样的写法就直接炸了
多加了一个enter标记,换成22行和105行那样的写法就妥了。
中途因为忘了改文件操作就交,又炸了两次
本来以为能1A来着……获得技能[迷之自信] @布吕歇尔自信姬
/*by SilverN*/
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int mxn=;
bool enter=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){
if(ch=='-')f=-;
// if(ch=='\r' || ch=='\n')return -1;//并没有卵用
ch=getchar();
}
while(ch>='' && ch<=''){
x=x*+ch-'';ch=getchar();
if(ch=='\r' || ch=='\n')enter=;
}
return x*f;
}
inline int min(int a,int b){return a<b?a:b;}
struct edge{
int v,nxt,f;
}e[mxn<<];
int hd[mxn],mct=;
void add_edge(int u,int v,int f){
e[++mct].v=v;e[mct].nxt=hd[u];e[mct].f=f;hd[u]=mct;return;
}
void insert(int u,int v,int c){
add_edge(u,v,c);add_edge(v,u,);return;
}
int S,T;
int d[];
queue<int>q;
bool BFS(){
memset(d,,sizeof d);
q.push(S);d[S]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=hd[u],v;i;i=e[i].nxt){
v=e[i].v;
if(e[i].f && !d[v]){
d[v]=d[u]+; q.push(v);
}
}
}
return d[T];
}
int DFS(int u,int lim){
if(u==T)return lim;
int f=,tmp;
for(int i=hd[u],v;i;i=e[i].nxt){
v=e[i].v;
if(e[i].f && d[v]==d[u]+ && (tmp=DFS(v,min(e[i].f,lim)))){
e[i].f-=tmp;
e[i^].f+=tmp;
lim-=tmp;
f+=tmp;
if(!lim)return f;
}
}
d[u]=;
return f;
}
int Dinic(){
int res=;
while(BFS())res+=DFS(S,INF);
return res;
}
int n,m;
int ans=;
void solve(){
ans-=Dinic();
for(int i=;i<=m;i++)
if(d[i])printf("%d ",i);
puts("");
for(int i=;i<=n;i++){
if(d[i+m])printf("%d ",i);
}
puts("");
printf("%d\n",ans);
return;
}
int main(){
// freopen("in.txt","r",stdin);
freopen("shuttle.in","r",stdin);
freopen("shuttle.out","w",stdout);
int i,j,x;
m=read();n=read();
S=;T=m+n+;
for(i=;i<=m;i++){
x=read();
ans+=x;
insert(S,i,x);
enter=;//
while(!enter){
x=read();
if(x==-)break;
insert(i,x+m,INF);
}
}
for(i=;i<=n;i++){
x=read();
insert(i+m,T,x);
}
solve();
return ;
}