网络流与线性规划24题
来源:互联网 发布:c语言入门小程序 编辑:程序博客网 时间:2024/06/01 09:56
留坑待填
网络流做题技巧:
1、板子很熟的情况下肉眼差错,放弃单步调试。
2、反复检查自己的网络流模型的正确性,确保正确才开始写。
3、手动构造多组数据卡自己的程序,网络流的题目通常样例很垃圾而且对拍不好写。
通用模板
最大流模板:
#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>#define N 10050#define INF 1<<30using namespace std;struct Node{int u,cap,rec; };vector<Node> e[N];int p[N],S,T;void add_Node(int a,int b,int v) {Node tmp;tmp.u = b;tmp.cap = v;tmp.rec = e[b].size();e[a].push_back(tmp);tmp.u = a;tmp.cap = 0;tmp.rec = e[a].size() - 1;e[b].push_back(tmp);return ;}bool BFS() {bool flag = false;memset(p,0,sizeof(p));queue<int> q;p[S] = 1;while (!q.empty()) {int u = q.front(); q.pop();if (u == T) flag = true;for (int i=0;i<e[u].size();i++) {int v = e[u][i].u;int cp = e[u][i].cap;if (cp > 0 && p[v] == 0) {p[v] = p[u] + 1;q.push(v);}}}return flag;}int DFS(int u,int flow) {if (u == T) return flow;int f = flow , g = 0;for (int i=0;i<e[u].size();i++) {int v = e[u][i].u;int cp = e[u][i].cap;int tmp = 0;if (cp > 0 && p[v] == p[u] + 1 && (tmp = DFS(v,min(f,cp))) > 0) {f -= tmp;g += tmp;e[u][i].cap -= tmp;int rc = e[u][i].rec;e[v][rc].cap += tmp;}}return g;}void build() {}int main(){build();int max_flow = 0;while (BFS()) max_flow += DFS(S,INF);int ans = max_flow;printf("%d\n",ans);return 0;}
24题建图
第一题:飞行员配对方案(二分图最大匹配)
建图:直接二分图建图,S连向所有皇家飞行员流量为INF,所有外国飞行员连向T流量为INF,每个皇家飞行员连向外国飞行员流量为1。最大流,最后输出所有的满流边的
void build() {while (1){scanf("%d%d",&x,&y);if (x == y && y == -1) break;if (x>y) swap(x,y);add_Node(x,y,1);}}
第二题:太空飞行计划问题(最大权闭合子图)
建图:超级源连向所有正权点,流量为权值,负权点连向超级汇,流量为权值(取绝对值),对所有的正权和负权的限制,从正权点连向负权点一条边,流量为INF(这条边不会被剪掉)。跑最小割,答案 = 正权点权值和 - 最小割。
思路:剪掉一个正权点即为放弃一个收益,剪掉一个负权点即为放弃一个限制。
void build() {scanf("%d%d",&m,&n);S = ++cnt; T = ++cnt;for (int i=1;i<=m;i++) l[i] = ++cnt;for (int i=1;i<=n;i++) r[i] = ++cnt;for (int i=1;i<=m;i++) {scanf("%d",&v);ans += v;add_Node(S,l[i],v);char ch = ' ';while (ch != '\n') {scanf("%d",&t); ch = getchar();add_Node(l[i],r[t],INF);}}for (int i=1;i<=n;i++) {scanf("%d",&v); add_Node(r[i],T,v);}}
第三题:最小路径覆盖问题(有向无环图最小路径覆盖)
建图:将所有的点拆成两个点<xi,yi>,S连向所有的xi容量为1,所有的yi连向T容量为1,对于原图中的每一条有向边E(u,v),在建图中加入<xu,yv>边,容量为1。答案等于点数-最大流。
思路:xi相当于一个点的出度点,yi相当于一个点的入度点。在最小路径覆盖问题中,一个点的出入度只能为0/1,所以它们连向超级源和超级汇的容量都为1。没有一条连向x,y的漫流边即为在路径覆盖中x,y被连接了。
void build() {S = ++cnt; T = ++cnt;for (int i=1;i<=n;i++) x[i] = ++cnt;for (int i=1;i<=n;i++) add_Node(S,x[i],1);for (int i=1;i<=n;i++) y[i] = ++cnt;for (int i=1;i<=n;i++) add_Node(y[i],T,1);for (int i=1;i<=m;i++) {int u = x[ e[i].a ] , v = y[ e[i].y ];add_Node(u,v,1);}}
建图:二分最大值,将所有的球拆点成xi,yi,分别连向超级源和超级汇,容量为1,对于球a,b(a<b且a+b=k^2),连接边<xa,yb>容量为1,若点数-最大流<=柱子数目,则判定为true.
思路:最小路径覆盖问题
void build() {S = ++cnt; T = ++cnt;for (int i=1;i<=n;i++) x[i] = ++cnt;for (int i=1;i<=n;i++) add_Node(S,x[i],1);for (int i=1;i<=n;i++) y[i] = ++cnt;for (int i=1;i<=n;i++) add_Node(y[i],T,1);for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)if (floor( sqrt(i+j) ) == sqrt(i+j)) add_Node(i,j,1);}
第五题:圆桌问题(二分图多重匹配)
建图:
S连向所有的单位,容量为该单位人数。
单位连向所有的餐桌,容量为1。
所有的餐桌连向T,容量为餐桌的容量。
最大流。输出所有满流的<单位、餐桌>边。
void build() {scanf("%d%d",&n,&m);S = ++cnt; T = ++cnt;for (int i=1;i<=n;i++) {scanf("%d",&t);l[i] = ++cnt;add_Node(S,l[i],t);}for (int i=1;i<=m;i++) {scanf("%d",&t);r[i] = ++cnt;add_Node(r[i],T,t);}for (int i=1;i<=n;i++)for (int j=1;j<=m;j++) add_Node(l[i],r[j],1);}
第六题:最长递增子序列问题(最大不相交路径)
诶一开始建的图是错的,少考虑了很多东西
第一问第二问DP,第三问网络流(需要借助前两问的dp数组)
令F[i]为最长的以i结尾的LIS的长度
建图:
对所有的点拆成xi,yi,且加入边xi,yi,如果是两端的点则容量为INF否则容量为1
对所有的F[i] = 1,S连向xi容量为1
对所有的F[i] = 第一问答案,yi连向T容量为1
对于每一对$ <i,j> $满足$ F[i]+1 = F[j] $ , $i<j$ 且 $ a[i] < a[j] $,建有向边<yi,xj>容量为1。
最大流。
void build() {for (int i=1;i<=n;i++)for (int j=i+1;j<=n;j++)if (F[i]+1 == F[j]) add_Node(i,j,1);}
1-6题完成时间:2016年12月10日-2016年12月13日
- 线性规划与网络流24题
- 线性规划与网络流24题
- 线性规划与网络流24题索引
- 线性规划与网络流24题
- 线性规划与网络流24题
- 网络流与线性规划24题
- 线性规划与网络流 24 题 题解
- 线性规划与网络流24
- [线性规划与网络流24题] 网络流常见模型
- 线性规划与网络流
- 【线性规划与网络流24题 24】骑士共存问题
- 线性规划与网络流24题 02太空飞行计划问题
- 线性规划与网络流24题 04魔术球问题
- 线性规划与网络流24题 05圆桌问题
- 线性规划与网络流24题 07试题库问题
- 线性规划与网络流24题 10餐巾计划问题
- 线性规划与网络流24题 11航空路线问题
- 网络流与线性规划24题02太空飞行计划问题
- linuxshell中"2>&1"含义
- 欢迎使用CSDN-markdown编辑器
- RabbitMq安装及java demo
- Struts 2.5.5 基本应用
- JavaWeb-Struts2-constant说明
- 网络流与线性规划24题
- 02.安装Sublime Text 3
- iScroll API 整理学习笔记
- TS Intro - PES packet format
- 第十三周文件操作1
- Arrays 类的相关方法使用,数组的拷贝,排序,二分法
- tomcat中日志输出的位置
- iOS中的NSURLProtocol
- 关于嵌入式系统的学习路线图