[SWUSTOJ1737] 太空飞行计划问题(最大权闭合子图,记录路径)

题目链接:https://www.oj.swust.edu.cn/problem/show/1737

很经典的建图,但是需要记录路径。

vis数组标记点是否被扩展,在每次dinic通过bfs扩展的时候假如被扩展的点,最后一次bfs随后不再有增广路便是最终结果。

  1 #include <bits/stdc++.h>
  2 using namespace std;
  3
  4 typedef struct Edge {
  5     int u, v, w, ww, next;
  6 }Edge;
  7
  8 const int inf = 0x7f7f7f7f;
  9 const int maxn = 3010;
 10 const int maxm = maxn << 2;
 11 int cnt, dhead[maxn];
 12 int cur[maxn], dd[maxn];
 13 bool vis[maxn];
 14 Edge dedge[maxm];
 15 int S, T, N;
 16
 17 void init() {
 18     memset(dhead, -1, sizeof(dhead));
 19     for(int i = 0; i < maxn; i++) dedge[i].next = -1;
 20     S = 0; cnt = 0;
 21 }
 22
 23 void adde(int u, int v, int w, int c1=0) {
 24     dedge[cnt].u = u; dedge[cnt].v = v; dedge[cnt].w = w; dedge[cnt].ww = w;
 25     dedge[cnt].next = dhead[u]; dhead[u] = cnt++;
 26     dedge[cnt].u = v; dedge[cnt].v = u; dedge[cnt].w = c1; dedge[cnt].ww = c1;
 27     dedge[cnt].next = dhead[v]; dhead[v] = cnt++;
 28 }
 29
 30 bool bfs(int s, int t, int n) {
 31     memset(vis, 0, sizeof(vis));
 32     queue<int> q;
 33     for(int i = 0; i < n; i++) dd[i] = inf;
 34     dd[s] = 0;
 35     q.push(s);
 36     while(!q.empty()) {
 37         int u = q.front(); q.pop();
 38         for(int i = dhead[u]; ~i; i = dedge[i].next) {
 39             if(dd[dedge[i].v] > dd[u] + 1 && dedge[i].w > 0) {
 40                 dd[dedge[i].v] = dd[u] + 1;
 41                 vis[dedge[i].v] = 1;
 42                 if(dedge[i].v == t) return 1;
 43                 q.push(dedge[i].v);
 44             }
 45         }
 46     }
 47     return 0;
 48 }
 49
 50 int dinic(int s, int t, int n) {
 51     int st[maxn], top;
 52     int u;
 53     int flow = 0;
 54     while(bfs(s, t, n)) {
 55         for(int i = 0; i < n; i++) cur[i] = dhead[i];
 56         u = s; top = 0;
 57         while(cur[s] != -1) {
 58             if(u == t) {
 59                 int tp = inf;
 60                 for(int i = top - 1; i >= 0; i--) {
 61                     tp = min(tp, dedge[st[i]].w);
 62                 }
 63                 flow += tp;
 64                 for(int i = top - 1; i >= 0; i--) {
 65                     dedge[st[i]].w -= tp;
 66                     dedge[st[i] ^ 1].w += tp;
 67                     if(dedge[st[i]].w == 0) top = i;
 68                 }
 69                 u = dedge[st[top]].u;
 70             }
 71             else if(cur[u] != -1 && dedge[cur[u]].w > 0 && dd[u] + 1 == dd[dedge[cur[u]].v]) {
 72                 st[top++] = cur[u];
 73                 u = dedge[cur[u]].v;
 74             }
 75             else {
 76                 while(u != s && cur[u] == -1) {
 77                     u = dedge[st[--top]].u;
 78                 }
 79                 cur[u] = dedge[cur[u]].next;
 80             }
 81         }
 82     }
 83     return flow;
 84 }
 85
 86 int n, m;
 87 char tmp[maxm];
 88 vector<int> s;
 89
 90 int main() {
 91     // freopen("in", "r", stdin);
 92     int pay;
 93     while(~scanf("%d%d",&n,&m)) {
 94         init();
 95         S = 0, T = m + n + 1, N = T + 1;
 96         int pos = 0;
 97         for(int i = 1; i <= n; i++) {
 98             scanf("%d",&pay);
 99             pos += pay;
100             adde(S, i, pay);
101             char p = getchar();
102             while((p = getchar()) != ‘\n‘) {
103                 pay = p - ‘0‘;
104                 while((p = getchar()) && p >= ‘0‘ && p <= ‘9‘) pay = pay * 10 + p - ‘0‘;
105                 adde(i, pay+n, inf);
106                 if(p == ‘\n‘) break;
107             }
108         }
109         for(int i = 1; i <= m; i++) {
110             scanf("%d", &pay);
111             adde(n+i, T, pay);
112         }
113         int ret = pos - dinic(S, T, N);
114         s.clear();
115         for(int i = 1; i <= n; i++) {
116             if(vis[i]) s.push_back(i);
117         }
118         printf("%d", s[0]);
119         for(int i = 1; i < s.size(); i++) printf(" %d", s[i]);
120         printf("\n");
121         s.clear();
122         for(int i = n+1; i <= n+m; i++) {
123             if(vis[i]) s.push_back(i-n);
124         }
125         printf("%d", s[0]);
126         for(int i = 1; i < s.size(); i++) printf(" %d", s[i]);
127         printf("\n");
128         printf("%d\n", ret);
129     }
130     return 0;
131 }
时间: 2024-10-05 08:08:30

[SWUSTOJ1737] 太空飞行计划问题(最大权闭合子图,记录路径)的相关文章

刷题总结——太空飞行计划(最大权闭合子图用最大流解决)

题目: 题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合 E={E1,E2,-,Em},和进行这些实验需要使用的全部仪器的集合 I={I1, I2,-In}. 实验 Ej 需要用到的仪器是 I 的子集 Rj∈I.配置仪器 Ik 的费用为 Ck 美元.实验 Ej 的赞助商已同意为该实验结果支付 Pj 美元.W 教授的任务是找出一个有效算法, 确定在一次太空飞行中要进行哪些实验并因此而配置哪些仪器才能使太空飞行的

LuoguP2762 太空飞行计划问题(最大权闭合子图,最小割)

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

1737: 太空飞行计划问题 最大权闭合子图

1.建立两个超级点S,T. 2.对每个实验跟S链接一条容量为收入的边. 3.对每个一起跟T链接一条容量为花费的边. 4.对每个实验要用到的一起链接一条容量为无穷大的边. 链表 #include <iostream> #include <queue> #include <vector> #include <cstdio> #include <cstring> using namespace std; const int MAXN = 101,MAX

太空飞行计划问题-最大权闭合图

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

【暖*墟】#网络流# 最大权闭合子图

[相关概念详解] 闭合图:有向图的一个点集,且这个点集的所有出边仍然指向该点集. 最大权闭合图:(每一个点有一个权值)在所有的合法闭合图中,点权之和最大的图. 处理问题:权值有正有负,重复选只算一次,选择有相互关联性 的问题. 首先有一个有向连通图(闭合图),每个点带有一个权值,例如: 造出一个超级源点S和一个超级汇点T,把S连边到所有带有正权的点上,每条边的容量是这个点的权: 把所有带负权的点连边到T,每条边的容量是这个点的权的相反数(正值).原来的边的容量设成无限大. 所有的点按权值的正负连

LibreOJ #6001. 「网络流 24 题」太空飞行计划 最大权闭合图

#6001. 「网络流 24 题」太空飞行计划 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合 E={E1,E2,?,Em} E = \{ E_1, E_2, \cdots, E_m \}E={E?1??,E?2??,?,E?m??},和进行这些实验

[网络流24题] 太空飞行计划 (最大权闭合子图---网络最大流)

727. [网络流24题] 太空飞行计划 ★★☆ 输入文件:shuttle.in 输出文件:shuttle.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业性实验而获取利润.现已确定了一个可供选择的实验集合E={E1,E2,…,Em},和进行这些实验需要使用的全部仪器的集合I={ I1, I2,…,In }.实验Ej 需要用到的仪器是I的子集Rj∈I.配置仪器Ik 的费用为ck 美元.实验Ej

洛谷 P2762 太空飞行计划问题

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

[网络流24题]太空飞行计划问题

Description $W$教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行可进行一系列商业 性实验而获取利润.现已确定了一个可供选择的实验集合$E={E_1,E_2,...,E_m}$,和进行这些实验需要使用的全部仪器的集合$I={I_1,I_2,...,I_n}$.实验$E_j$需要用到的仪器是$I$的子集$R_j\;\in\;I$.配置仪器$I_k$的费用为$c_k$美元.实验$E_j$的赞助商已同意为该实验结果支付$p_j$美元.$W$教授的任务是确定在一次太空飞行中要进行哪些