题目1 ZJOI 最小割

题目大意:

求一个无向带权图两点间的最小割,询问小于等于c的点对有多少。

算法讨论: 最小割 分治

代码:

#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector> using namespace std;
const int N = 150 + 5;
const int M = 3000 + 5;
const int oo = 0x3f3f3f3f;
#define inf oo int n, m;
bool mark[N];
int a[N], tmp[N], ans[N][N]; struct Edge {
int from, to, cap, flow;
Edge(int u = 0, int v = 0, int c = 0, int f = 0) :
from(u), to(v), cap(c), flow(f) {}
}; struct Dinic {
int n, mm, s, t;
int dis[N], cur[N], que[N * 10];
bool vis[N];
vector <Edge> edges;
vector <int> G[N]; void clear() {
for(int i = 0; i <= n; ++ i) G[i].clear();
edges.clear();
} void add(int from, int to, int cap) {
edges.push_back(Edge(from, to, cap, 0));
edges.push_back(Edge(to, from, cap, 0));
mm = edges.size();
G[from].push_back(mm - 2);
G[to].push_back(mm - 1);
} bool bfs() {
int head = 1, tail = 1;
memset(vis, false, (n + 1) * sizeof (bool));
dis[s] = 0; vis[s] = true; que[head] = s;
while(head <= tail) {
int x = que[head];
for(int i = 0; i < (signed) G[x].size(); ++ i) {
Edge &e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow) {
vis[e.to] = true;
dis[e.to] = dis[x] + 1;
que[++ tail] = e.to;
}
}
++ head;
}
return vis[t];
} int dfs(int x, int a) {
if(x == t || a == 0) return a;
int flw = 0, f;
for(int &i = cur[x]; i < (signed) G[x].size(); ++ i) {
Edge &e = edges[G[x][i]];
if(dis[e.to] == dis[x] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) {
e.flow += f; edges[G[x][i] ^ 1].flow -= f; flw += f; a -= f;
if(a == 0) break;
}
}
return flw;
} int maxflow(int s, int t) {
this->s = s; this->t = t;
int flw = 0;
while(bfs()) {
memset(cur, 0, sizeof cur);
flw += dfs(s, oo);
}
return flw;
} void rebuild() {
for(int i = 0; i < (signed) edges.size(); ++ i)
edges[i].flow = 0;
} void dfs(int u) {
mark[u] = true;
for(int i = 0; i < (signed) G[u].size(); ++ i) {
Edge e = edges[G[u][i]];
if(!mark[e.to] && e.cap > e.flow) {
dfs(e.to);
}
}
}
}net; void Divide(int l, int r) {
if(l >= r) return;
net.rebuild();
int nowflow = net.maxflow(a[l], a[r]);
memset(mark, false, (n + 1) * sizeof (bool));
net.dfs(a[l]);
for(int i = 1; i <= n; ++ i)
if(mark[i])
for(int j = 1; j <= n; ++ j)
if(!mark[j])
ans[i][j] = min(ans[i][j], nowflow), ans[j][i] = ans[i][j];
int L = l, R = r;
for(int i = l; i <= r; ++ i)
if(mark[a[i]]) tmp[L ++] = a[i];
else tmp[R --] = a[i];
for(int i = l; i <= r; ++ i) a[i] = tmp[i];
Divide(l, L - 1); Divide(R + 1, r);//这不能二分一个Mid,因为S集和T集的大小不一定相同
} int main() {
int T, u, v, c, q;
scanf("%d", &T);
while(T --) {
net.clear();
scanf("%d%d", &n, &m); net.n = n;
for(int i = 1; i <= n; ++ i) a[i] = i;
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= n; ++ j) ans[i][j] = inf;
for(int i = 1; i <= m; ++ i) {
scanf("%d%d%d", &u, &v, &c);
net.add(u, v, c);
}
Divide(1, n);
scanf("%d", &q);
for(int i = 1; i <= q; ++ i) {
int tmp = 0;
scanf("%d", &c);
for(int u = 1; u <= n; ++ u) {
for(int v = u + 1; v <= n; ++ v) {
if(ans[u][v] <= c) {
++ tmp;
}
}
}
printf("%d\n", tmp);
}
puts("");
}
return 0;
}

题目2 CQOI2016 不同的最小割

题目大意:

求所有点对问不同的最小割数目。

算法讨论: 最小割 分治

和上面的一个题有区别么?

代码:

#include <cstdlib>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <set> using namespace std;
const int N = 850 + 5;
const int M = 8500 + 5;
const int oo = 0x3f3f3f3f; int n, m;
int ans[N][N], tmp[N], a[N];
bool mark[N];
set <int> lts; struct Edge {
int from, to, cap, flow;
Edge(int u = 0, int v = 0, int cap = 0, int flow = 0):
from(u), to(v), cap(cap), flow(flow) {}
}; struct Dinic {
int n, m, s, t;
int dis[N], cur[N], que[N * 10];
bool vis[N];
vector <Edge> edges;
vector <int> G[N]; void add(int from, int to, int cap) {
edges.push_back(Edge(from, to, cap, 0));
edges.push_back(Edge(to, from, cap, 0));
m = edges.size();
G[from].push_back(m - 2);
G[to].push_back(m - 1);
} bool bfs() {
int head = 1, tail = 1;
memset(vis, false, (n + 1) * sizeof (bool));
dis[s] = 0; vis[s] = true; que[head] = s;
while(head <= tail) {
int x = que[head];
for(int i = 0; i < (signed) G[x].size(); ++ i) {
Edge &e = edges[G[x][i]];
if(!vis[e.to] && e.cap > e.flow) {
vis[e.to] = true;
dis[e.to] = dis[x] + 1;
que[++ tail] = e.to;
}
}
++ head;
}
return vis[t];
} int dfs(int x, int a) {
if(x == t || a == 0) return a;
int flw = 0, f;
for(int &i = cur[x]; i < (signed) G[x].size(); ++ i) {
Edge &e = edges[G[x][i]];
if(dis[e.to] == dis[x] + 1 && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) {
e.flow += f; edges[G[x][i] ^ 1].flow -= f; a -= f; flw += f;
if(a == 0) break;
}
}
return flw;
} int maxflow(int s, int t) {
this->s = s; this->t = t;
int flw = 0;
while(bfs()) {
memset(cur, 0, sizeof cur);
flw += dfs(s, oo);
}
return flw;
} void rebuild() {
for(int i = 0; i < (signed) edges.size(); ++ i)
edges[i].flow = 0;
} void dfs(int u) {
mark[u] = true;
for(int i = 0; i < (signed) G[u].size(); ++ i) {
Edge e = edges[G[u][i]];
if(!mark[e.to] && e.cap > e.flow)
dfs(e.to);
}
}
}net; void Divide(int l, int r) {
if(l >= r) return;
net.rebuild();
int nowflow = net.maxflow(a[l], a[r]);
memset(mark, false, (n + 1) * sizeof(bool));
net.dfs(a[l]);
for(int i = 1; i <= n; ++ i)
if(mark[i])
for(int j = 1; j <= n; ++ j)
if(!mark[j])
ans[i][j] = min(ans[i][j], nowflow), ans[j][i] = ans[i][j];
int L = l, R = r;
for(int i = l; i <= r; ++ i)
if(mark[a[i]]) tmp[L ++] = a[i];
else tmp[R --] = a[i];
for(int i = l; i <= r; ++ i)
a[i] = tmp[i];
Divide(l, L - 1); Divide(R + 1, r);
} int main() {
int u, v, c;
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; ++ i) {
scanf("%d%d%d", &u, &v, &c);
net.add(u, v, c);
}
for(int i = 1; i <= n; ++ i) a[i] = i;
for(int i = 1; i <= n; ++ i)
for(int j = 1; j <= n; ++ j) ans[i][j] = oo;
net.n = n;
Divide(1, n);
for(int i = 1; i <= n; ++ i) {
for(int j = i + 1; j <= n; ++ j) {
lts.insert(ans[i][j]);
}
}
printf("%d\n", lts.size());
return 0;
}

ZJOI 最小割 CQOI 不同的最小割 (最小割分治)的更多相关文章

  1. 最小割树(Gomory-Hu Tree)求无向图最小割详解 附 BZOJ2229,BZOJ4519题解

    最小割树(Gomory-Hu Tree) 前置知识 Gomory-Hu Tree是用来解决无向图最小割的问题的,所以我们需要了解无向图最小割的定义 和有向图类似,无向图上两点(x,y)的割定义为一个边 ...

  2. EBS oracle 批量导入更新MOQ(最小拆分量、采购提前期、最小订购量、最小包装量)

    EXCEL的列:组织id,供应商编号,供应商地点,料号,最小拆分量.采购提前期.最小订购量.最小包装量 --采购导入更新MOQ四个值,若有为空的那列,会保留原来的值,不会去更新那列的值 PROCEDU ...

  3. delphi中最小化其他程序及所有程序最小化(使用 shell.minimizeAll 和自己寻找窗口这两种办法)

    1.所有程序最小化 uses ComObj;   var    shell : OleVariant; begin      shell := CreateOleObject('Shell.Appli ...

  4. 最小正子序列(序列之和最小,同时满足和值要最小)(数据结构与算法分析——C语言描述第二章习题2.12第二问)

    #include "stdio.h" #include "stdlib.h" #define random(x) (rand()%x) void creat_a ...

  5. ACdream 1135(MST-最小生成树边上2个值,维护第一个最小的前提下让还有一个最小)

    F - MST Time Limit: 2000/1000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others) SubmitStatu ...

  6. 【BZOJ-4435】Juice Junctions 最小割树(分治+最小割)+Hash

    4435: [Cerc2015]Juice Junctions Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 20  Solved: 11[Submi ...

  7. HDU3870 Catch the Theves(平面图最小割转最短路)

    题目大概说给一个n×n的方格,边有权值,问从求(1,1)到(n,n)的最小割. 点达到了160000个,直接最大流不好.这题的图是平面图,求最小割可以转化成求其对偶图的最短路,来更高效地求解: 首先源 ...

  8. hiho 第116周,最大流最小割定理,求最小割集S,T

    小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c ...

  9. poj 1815 Friendship 字典序最小+最小割

    题目链接:http://poj.org/problem?id=1815 In modern society, each person has his own friends. Since all th ...

随机推荐

  1. sql语句各种九九乘法表

    下面用while 和 if 条件写的SQL语句的四种九九乘法表 --9x9 左下角 ) BEGIN SET @S='' WHILE @J<=@I BEGIN )))))) END PRINT @ ...

  2. angular-route 里面templeteUrl 动态加载

    https://segmentfault.com/q/1010000002524964

  3. .net转php laraval框架学习系列(四) 项目实战---View

    laravel的参考文档中view的讲解有些简单. 在实际项目开发中view的灵活性其实是非常大. 首先来看看laravel中的布局页 和asp.net mvc中有什么不同 <!DOCTYPE ...

  4. Page.ClientScript.RegisterStartupScript函数的使用

    Page.ClientScript.RegisterStartupScript(type,key,script,addScriptTags);type要注册的启动脚本的类型.key要注册的启动脚本的键 ...

  5. 关于js事件冒泡和时间捕获

    (1)冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发. IE 5.5: div -> body -> document IE 6.0: div ...

  6. js 发送ajax请求(XMLHttpRequest)

    <!DOCTYPE html><html> <head> <title></title> <script type="tex ...

  7. iOS 拨打电话三种方式总结

    1,这种方法,拨打完电话回不到原来的应用,会停留在通讯录里,而且是直接拨打,不弹出提示NSMutableString * str=[[NSMutableString alloc] initWithFo ...

  8. PHP-FPM的STATUS显示配置

    希望能在优化PHP-FPM方面作一个改进.. 参考URL: http://www.ttlsa.com/php/use-php-fpm-status-page-detail/ http://www.li ...

  9. openStack kilo 手动Manual部署随笔记录

    一 ,基于neutron网络资源主机(控制节点,网络节点,计算节点)网络规划配置 1, controller.cc 节点 网络配置截图

  10. 传智播客学习之HTML基础语法

    一.基本格式 1.不用区分大小写. 2.HTML代码由<html>开始</html>结束.里面由头部分<head></head>和体部分<body ...