2324. 生活的艰辛(网络流,最小割,最大密度子图)#困难,重点难点

本文主要是介绍2324. 生活的艰辛(网络流,最小割,最大密度子图)#困难,重点难点,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

活动 - AcWing

约翰是一家公司的 CEO。

公司的股东决定让他的儿子斯科特成为公司的经理。

约翰十分担心,儿子会因为在经理岗位上表现优异而威胁到他 CEO 的位置。

因此,他决定精心挑选儿子要管理的团队人员,让儿子知道社会的险恶。

已知公司中一共有 n 名员工,员工之间共有 m 对两两矛盾关系。

如果将一对有矛盾的员工安排在同一个团队,那么团队的管理难度就会增大。

一个团队的管理难度系数等于团队中的矛盾关系对数除以团队总人数。

团队的管理难度系数越大,团队就越难管理。

约翰希望给儿子安排的团队的管理难度系数尽可能大。

请帮帮他。

3155_1.png

以上图为例,管理难度系数最大的团队由 1,2,4,5 号员工组成,他们 4 人中共有 5 对矛盾关系,所以管理难度系数为 54。

如果我们将 3 号员工也加入到团队之中,那么管理难度系数就会降至 65。

输入格式

第一行包含两个整数 n 和 m。

接下来 m 行,每行包含两个整数 ai和 bi,表示员工 ai 和 bi 之间存在矛盾。

所有员工编号从 1 到 n。

每个矛盾对最多在输入中出现一次,且介绍矛盾对时,员工介绍顺序是随意的。

输出格式

首先输出一个整数 k,表示安排给斯科特的团队人员数量。

接下来 k 行,以升序输出团队每个成员的编号,每行一个。

如果答案不唯一,则输出任意一种即可。

注意:至少要选择一名员工。

数据范围

1≤n≤100,
0≤m≤1000
1≤k≤n

输入样例1:
5 6
1 5
5 4
4 2
2 5
1 2
3 1
输出样例1:
4
1
2
4
5
输入样例2:
4 0
输出样例2:
1
1
提示

注意样例 22 中,任意团队的管理困难系数都是 00,这种情况输出任意非空方案即可。

解析: 

 最大密度子图详细证明请参考讲义(作者小小_88):最大密度子图的相关概念 - AcWing

关于最小割得更详细了解请阅读胡伯涛的论文:《最小割模型在信息学竞赛中的应用 》: https://www.studocu.com/row/document/changsha-university-of-science-and-technology/computer-algorithm/7%E8%83%A1%E4%BC%AF%E6%B6%9B%E6%9C%80%E5%B0%8F%E5%89%B2%E6%A8%A1%E5%9E%8B%E5%9C%A8%E4%BF%A1%E6%81%AF%E5%AD%A6%E7%AB%9E%E8%B5%9B%E4%B8%AD%E7%9A%84%E5%BA%94%E7%94%A8-changsha-university-of-science-and-technology/26399377

本题就是密度子图的一个应用,给我们 n 个点,m 条边,让我们求最大密度子图,本题需要输出方案,由于已经证明过密度子图和割一一对应,且 V′=S−{s} 所以只要找出任何一个割,再把源点删掉,剩下的点集就是一个合法方案。怎么找出一个割呢,从源点出发沿着容量 >0 的边走,凡是走得到的点都属于 S,反之属于 T。

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<math.h>
#include<map>
#include<sstream>
#include<deque>
#include<unordered_map>
#include<unordered_set>
#include<bitset>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N = 1e2 + 10, M = (1e3 + N * 2) * 2, INF = 0x3f3f3f3f;
int n, m, S, T;
int h[N], e[M], ne[M], idx;
double f[M];
int q[N], d[N], cur[N];
int ans;
bool st[N];
int dg[N];
struct egde {int a, b;
}edges[M];void add(int a, int b, double d1, double d2) {e[idx] = b, f[idx] = d1, ne[idx] = h[a], h[a] = idx++;e[idx] = a, f[idx] = d2, ne[idx] = h[b], h[b] = idx++;
}void build(double g) {memset(h, -1, sizeof h);idx = 0;for (int i = 1; i <= m; i++)add(edges[i].a, edges[i].b, 1, 1);for (int i = 1; i <= n; i++) {add(S,i, m, 0);add(i, T, m + 2 * g - dg[i], 0);}
}double find(int u, double limit) {if (u == T)return limit;double flow = 0;for (int i = cur[u]; i != -1 && flow < limit; i = ne[i]) {int j = e[i];cur[u] = i;if (d[j] == d[u] + 1 && f[i] > 0) {double t = find(j, min(f[i], limit - flow));if (t <= 0)d[j] = -1;f[i] -= t, f[i ^ 1] += t, flow += t;}}return flow;
}bool bfs() {int hh = 0, tt = 0;memset(d, -1, sizeof d);q[0] = S, d[S] = 0, cur[S] = h[S];while (hh <= tt) {int t = q[hh++];for (int i = h[t]; i != -1; i = ne[i]) {int j = e[i];if (d[j] == -1 && f[i] > 0) {d[j] = d[t] + 1;cur[j] = h[j];if (j == T)return 1;q[++tt] = j;}}}return 0;
}double dinic(double mid) {build(mid);double ret = 0, flow;while (bfs())while (flow = find(S, INF))ret += flow;return ret;
}void dfs(int u) {st[u] = 1;if (u != S)ans++;for (int i = h[u]; i != -1; i = ne[i]) {int j = e[i];if (!st[j] && f[i] > 0)dfs(j);}
}int main() {cin >> n >> m;S = 0, T = n + 1;for (int i = 1; i <= m; i++) {scanf("%d%d", &edges[i].a, &edges[i].b);dg[edges[i].a]++, dg[edges[i].b]++;}double l = 0, r = m;while (r - l > 1e-8) {double mid = (r + l) / 2;double t = dinic(mid);if (n * m - t > 0)l = mid;else r = mid;}dinic(l);dfs(S);if (!ans)cout << 1 << endl << 1 << endl;else {cout << ans << endl;for (int i = 1; i <= n; i++) {if (st[i]) printf("%d\n", i);}}return 0;
}

这篇关于2324. 生活的艰辛(网络流,最小割,最大密度子图)#困难,重点难点的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/760134

相关文章

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

poj 3723 kruscal,反边取最大生成树。

题意: 需要征募女兵N人,男兵M人。 每征募一个人需要花费10000美元,但是如果已经招募的人中有一些关系亲密的人,那么可以少花一些钱。 给出若干的男女之间的1~9999之间的亲密关系度,征募某个人的费用是10000 - (已经征募的人中和自己的亲密度的最大值)。 要求通过适当的招募顺序使得征募所有人的费用最小。 解析: 先设想无向图,在征募某个人a时,如果使用了a和b之间的关系

poj 3258 二分最小值最大

题意: 有一些石头排成一条线,第一个和最后一个不能去掉。 其余的共可以去掉m块,要使去掉后石头间距的最小值最大。 解析: 二分石头,最小值最大。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <c

poj 2175 最小费用最大流TLE

题意: 一条街上有n个大楼,坐标为xi,yi,bi个人在里面工作。 然后防空洞的坐标为pj,qj,可以容纳cj个人。 从大楼i中的人到防空洞j去避难所需的时间为 abs(xi - pi) + (yi - qi) + 1。 现在设计了一个避难计划,指定从大楼i到防空洞j避难的人数 eij。 判断如果按照原计划进行,所有人避难所用的时间总和是不是最小的。 若是,输出“OPETIMAL",若