分类
标签
2-SAT AC自动机 BFS CDQ dfs DP fail树 FFT FFT&NTT FWT hash KD-Tree KMP LCA SPFA STL Tarjan Treap Trie 主席树 乱搞 二分 二分图匹配 二分答案 二维SPFA 交互 位运算 其他 最小生成树 分块 区间DP 半平面交 博弈论 可持久化 可持久化Trie树 后缀数组 图库 平衡树 并查集 插头DP 数学 数论 无旋Treap 日记 暴力 权值树状数组 栈 树DP 树套树 树状数组 树贪心 概率DP 模拟 欧拉定理 点分治 状压DP 生成函数 矩阵乘 线性规划 线段树 组合 网络流 群论 莫比乌斯反演 计算几何 贪心 费用流 高斯消元
590 字
3 分钟
网络流24题 太空飞行计划
【问题描述】
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
题解
最大权闭合子图 很裸的题,复习一下板子
/*
* @Author: WildRage
* @Date: 2017-06-13 21:23:24
* @Last Modified by: WildRage
* @Last Modified time: 2017-06-13 21:48:22
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int INF=0x7fffffff;
struct edge{
int END,next,cap;
}v[100005];
int first[1005],p;
void add(int a,int b,int c){
v[p].END=b;v[p].next=first[a];v[p].cap=c;first[a]=p++;
v[p].END=a;v[p].next=first[b];v[p].cap=0;first[b]=p++;
}
int cur[1005],dis[1005];
bool vis[1005];
bool BFS(int S,int E){
memset(vis,0,sizeof(vis));
memset(dis,-1,sizeof(dis));
queue<int> Q;
Q.push(S);
dis[S]=0;vis[S]=1;
while(!Q.empty()){
int u=Q.front();Q.pop();
for(int i=first[u];i!=-1;i=v[i].next){
if(!vis[v[i].END]&&v[i].cap>0){
vis[v[i].END]=1;
dis[v[i].END]=dis[u]+1;
if(v[i].END==E)return 1;
Q.push(v[i].END);
}
}
}
return 0;
}
int DFS(int S,int E,int a){
if(S==E||a==0)return a;
int flow=0,f;
for(int i=first[S];i!=-1;i=v[i].next){
if(dis[S]+1==dis[v[i].END]&&(f=DFS(v[i].END,E,min(a,v[i].cap)))>0){
v[i].cap-=f;
v[i^1].cap+=f;
flow+=f;
a-=f;
}
}
if(!flow)dis[S]=-1;
return flow;
}
int Dinic(int S,int E){
int ans=0;
while(BFS(S,E)){
ans+=DFS(S,E,INF);
}
//printf("%d\n",ans);
//while(1);
return ans;
}
int Main()
{
memset(first,-1,sizeof(first));
int n,m;
freopen("shuttle.in","r",stdin);
freopen("shuttle.out","w",stdout);
scanf("%d%d",&n,&m);
int ans=0;
char ch;
for(int x,i=1;i<=n;i++){
scanf("%d",&x);ans+=x;
add(0,i,x);
while(1){
while((ch=getchar())==' ');
ungetc(ch,stdin);
if(ch=='\n'||ch=='\r')break;
scanf("%d",&x);
add(i,x+n,INF);
}
}
for(int x,i=1;i<=m;i++){
scanf("%d",&x);
add(i+n,m+n+1,x);
}
ans=ans-Dinic(0,n+m+1);
for(int i=1;i<=n;i++)
if(dis[i]>=0)
printf("%d ",i);
puts("");
for(int i=1;i<=m;i++)
if(dis[i+n]>=0)
printf("%d ",i);
puts("");
printf("%d\n",ans);
return 0;
}
int Wild=Main();
int main(){;}