题目传送门



题解

  • 直接建图跑网络流即可。
  • 对于区间的最大流,可以使用线段树,也可以直接加边。
  • 注意数据范围不要太小。(奇奇怪怪,开小一点就超时???什么毛病)

AC-Code

#include <bits/stdc++.h>using namespace std;
typedef long long ll;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);const int inf = 0x3f3f3f3f;
const int maxn = 1e6 + 7;struct Edge {int to;int next;int val;
};
struct Dinic {Edge edge[maxn << 1];   // 双向边,开 2 倍数组int head[maxn];int cnt; // 边的数量,从 0 开始编号int depth[maxn]; // 分层图标记深度void init() {memset(head, -1, sizeof(head));cnt = 0;}void add(int u, int v, int w) {edge[cnt].to = v;edge[cnt].next = head[u];edge[cnt].val = w;head[u] = cnt++;}// bfs分层图bool bfs(int s, int t) {queue<int>q;memset(depth, 0, sizeof depth);depth[s] = 1; // 源点深度为 1q.push(s);while (!q.empty()) {int u = q.front();q.pop();for (int i = head[u]; ~i; i = edge[i].next) {int v = edge[i].to;if (edge[i].val > 0 && depth[v] == 0) { // 如果残量不为0,且 v 还未分配深度depth[v] = depth[u] + 1;q.push(v);}}}return depth[t]; // 汇点深度为 0:不存在分层图,返回false;//           非 0 :存在增广路,返回true}// dfs寻找增广路int dfs(int u, int flow, int t) {if (u == t || flow <= 0) // 到达汇点return flow;int rest = flow;for (int i = head[u]; ~i; i = edge[i].next) {int v = edge[i].to;if (depth[v] == depth[u] + 1 && edge[i].val != 0) { // 满足分层图、残量>0 两个条件int k = dfs(v, min(rest, edge[i].val), t); // 向下增广rest -= k;edge[i].val -= k; // 正向边减edge[i ^ 1].val += k; // 反向边加}}return flow - rest; // flow:推送量,rest:淤积量,flow - rest:接受量/成功传递量}int maxflow(int s, int t) {int ans = 0;while (bfs(s, t)) {while (int d = dfs(s, inf, t))ans += d;}return ans;}
}DC;int sum[maxn];  // sum[i]:高度为i的树的数量
int main() {ios;int t;  cin >> t;while (t--) {DC.init();int n, m, k;  cin >> n >> m >> k;for (int i = 0; i <= k; ++i)    sum[i] = 0;for (int i = 0; i < n; ++i) {int x;    cin >> x;++sum[x];}int num = k;   // 拓展结点,先++再使用,从k+1起始for (int i = 1; i <= m; ++i) {int op, c;   cin >> op >> c;if (op == 1) {int a0, b0;  cin >> a0 >> b0;DC.add(a0, b0, c);  DC.add(b0, a0, 0);}else if (op == 2) {int a1, a2, b1; cin >> a1 >> a2 >> b1;++num;for (int j = a1; j <= a2; ++j) {DC.add(j, num, c);   DC.add(num, j, 0);}DC.add(num, b1, c);  DC.add(b1, num, 0);}else if (op == 3) {int a1, b1, b2;    cin >> a1 >> b1 >> b2;++num;DC.add(a1, num, c); DC.add(num, a1, 0);for (int j = b1; j <= b2; ++j) {DC.add(num, j, c);    DC.add(j, num, 0);}}else if (op == 4) {int a1, a2, b1, b2;    cin >> a1 >> a2 >> b1 >> b2;++num;for (int j = a1; j <= a2; ++j) {DC.add(j, num, c);   DC.add(num, j, 0);}DC.add(num, num + 1, c);    DC.add(num + 1, num, 0);++num;for (int j = b1; j <= b2; ++j) {DC.add(num, j, c);  DC.add(j, num, 0);}}}int start = 0, end = ++num;for (int i = 1; i <= k; ++i) {if (sum[i]) {DC.add(start, i, sum[i]); DC.add(i, start, 0);}}DC.add(k, end, n);    DC.add(end, k, 0);cout << DC.maxflow(start, end) << endl;}
}

“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——G.养花【网络流】相关推荐

  1. 科林明伦杯”哈尔滨理工大学第十届程序设计竞赛B(减成1)

    科林明伦杯"哈尔滨理工大学第十届程序设计竞赛 存在n个数,每次操作可以任选一个区间使得区间内的所有数字减一.问最少多少次操作,可以让所有数都变成1. 数据保证一定有解. 输入描述: 输入t, ...

  2. “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛) 题解

    "科林明伦杯"哈尔滨理工大学第十届程序设计竞赛(同步赛) 题解 萌新又来写题解啦 原题链接 B 减成一 题意:存在n个数,每次操作可以任选一个区间使得区间内的所有数字减一.问最少多 ...

  3. “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛 E 赛马 python

    "科林明伦杯"哈尔滨理工大学第十届程序设计竞赛 E 赛马 python E 好家伙 田忌赛马真就 匹配就不解释了 思路,主要咱不止一匹马 所以就最好的比 对方比这个数小的即可 所以 ...

  4. “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛)---全题目+题解

    文章目录 A.点对最大值 B.减成一 C.面积 D.扔硬币 E.赛马 F.三角形 G.养花 H.直线 I.字典序 J.最大值 A.点对最大值 链接:https://ac.nowcoder.com/ac ...

  5. “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛) F

    F 三角形 链接:https://ac.nowcoder.com/acm/contest/5758/F 来源:牛客网 小明有一根长度为a的木棒,现在小明想将木棒分为多段(每段木棒长度必须为整数), 使 ...

  6. 科林明伦杯 哈尔滨理工大学第十届程序设计竞赛 (补)

    B减成一 利用差分数组,把前后差为正的数都加起来,这里a[0]要设置为1. #include <iostream> #define ll long longusing namespace ...

  7. “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛

    链接 B. 减成一 题目描述 存在n个数,每次操作可以任选一个区间使得区间内的所有数字减一.问最少多少次操作,可以让所有数都变成1. Solution 情况1:如果num[i] >= num[i ...

  8. “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛部分题解

    B 减成一 差分 输入同时对原数组处理,最终区间减数即为每次差分的累加和 int a[100010]; int b[100010]; int main() {t=read();while(t --) ...

  9. “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛) 点对最大值 dp

    链接:https://ac.nowcoder.com/acm/contest/5758/A 来源:牛客网 题目描述 这里有一棵树,每个点和每条边都存在一个价值.对于树上点对的价值,包括点对的起点和终点 ...

最新文章

  1. MNIST手写数字识别
  2. MySQL卸载5.重新安装 8.0.20教程(windows 64位)
  3. 通过分区在Kafka中实现订单保证人
  4. Unity经典游戏教程之:是男人就下100层
  5. Linux ALSA声卡驱动之四:Control设备的创建
  6. 初识空中计算(Over-the-Air Computation)
  7. ZZULIOJ 1130: 杨辉三角
  8. 第6章 循环结构程序设计
  9. 第6章 见缝插圆(《C和C++游戏趣味编程》配套教学视频)
  10. 马云卸任阿里巴巴董事局主席;苹果承认违法中国劳动法;IntelliJ IDEA 2019.2.2 发布​ | 极客头条...
  11. 大数据“下田”,未来农业将成为世界上最重要的产业之一
  12. python 随机密码生成_python生成随机密码,包含大小写和数字
  13. 黑苹果AX201网卡驱动小白教程,小新pro13不换网卡也能上网!
  14. WinCE驱动之Touch Panel(开发详解)
  15. tp5.0 百度编辑器上传图片到阿里云oss
  16. 字节跳动-大数据研发面试准备
  17. “拖延症”的良方——对于追求完美,自制力差,情绪化的人很受用。 【谨以此文共勉。】 来源: 胡野的日志
  18. 贪吃蛇“大作战”(二)
  19. Dropbox使用问题
  20. scikit-learn中的KMeans聚类实现

热门文章

  1. ctf 抓捕赵德汉_第三届网络空间安全技术大赛WriteUp(cstc2017)
  2. Mysql数据库 汉字转拼音全拼
  3. 利用FFmpeg API进行字符叠加和加水印
  4. 了解什么是枚举(enumeration)
  5. Android使用NFC模拟IC卡
  6. java 1st 2nd 3rd 4th_1st(3rd)
  7. 传奇手游服务器搭建_传奇私服服务器端在云服务器架设,全版本通用的传奇游戏架设教程...
  8. 我跨过山和大海,穿过人山人海,只为寻找到你
  9. MATLAB写UCB算法,科学网—【RL系列】Multi-Armed Bandit问题笔记——UCB策略实现 - 管金昱的博文...
  10. Spring MVC之redirect、forward和普通跳转