SPFA+Dinic HDOJ 5294 Tricks Device
/*
题意:一无向图,问至少要割掉几条边破坏最短路,问最多能割掉几条边还能保持最短路
SPFA+Dinic:SPFA求最短路时,用cnt[i]记录到i最少要几条边,第二个答案是m - cnt[n]
最大流==最小割,套个Dinic模板,以后再理解算法。。。
*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
using namespace std; const int MAXN = 2e3 + 10;
const int MAXM = 6e4 + 10;
const int INF = 0x3f3f3f3f;
struct Edge {
int v, w;
};
struct Flow {
int v, cap, rev;
};
bool vis[MAXN];
int cnt[MAXN];
int d[MAXN];
int lv[MAXN];
int it[MAXN];
vector<Edge> G[MAXN];
vector<Flow> F[MAXN];
int n, m; void add_edge(int u, int v, int cap) {
F[u].push_back ((Flow) {v, cap, (int) F[v].size ()});
F[v].push_back ((Flow) {u, 0, (int) F[u].size ()-1});
} void BFS(int s) {
memset (lv, -1, sizeof (lv));
queue<int> Q; Q.push (s); lv[s] = 0; while (!Q.empty ()) {
int u = Q.front (); Q.pop ();
for (int i=0; i<F[u].size (); ++i) {
Flow &e = F[u][i];
if (e.cap > 0 && lv[e.v] < 0) {
lv[e.v] = lv[u] + 1;
Q.push (e.v);
}
}
}
} int DFS(int u, int t, int f) {
if(u == t) return f;
vis[u] = true;
for (int &i=it[u]; i<F[u].size (); ++i) {
Flow &e = F[u][i];
if (e.cap > 0 && lv[u] < lv[e.v]) {
int d = DFS (e.v, t, min (f, e.cap));
if (d > 0) {
e.cap -= d; F[e.v][e.rev].cap += d;
return d;
}
}
}
return 0;
} int Dinic(int s, int t) {
int flow = 0, f;
for (; ;) {
BFS (s);
if (lv[t] < 0) return flow;
memset (it, 0, sizeof (it));
while ((f = DFS (s, t, INF)) > 0) flow += f;
}
} void build_graph(void) {
for (int i=1; i<=n; ++i) {
for (int j=0; j<G[i].size (); ++j) {
Edge &e = G[i][j];
if (d[i] + e.w == d[e.v]) {
add_edge (i, e.v, 1);
add_edge (e.v, i, 0);
}
}
}
} void SPFA(int s) {
for (int i=1; i<=n; ++i) {
d[i] = (i == s) ? 0 : INF;
cnt[i] = (i == s) ? 0 : INF;
}
memset (vis, false, sizeof (vis)); vis[s] = true;
queue<int> Q; Q.push (s); while (!Q.empty ()) {
int u = Q.front (); Q.pop ();
vis[u] = false;
for (int i=0; i<G[u].size (); ++i) {
int v = G[u][i].v, w = G[u][i].w;
if (d[v] == d[u] + w) cnt[v] = min (cnt[v], cnt[u] + 1);
if (d[v] > d[u] + w) {
d[v] = d[u] + w; cnt[v] = cnt[u] + 1;
if (!vis[v]) {
vis[v] = true; Q.push (v);
}
}
}
}
} int main(void) { //HDOJ 5294 Tricks Device
//freopen ("G.in", "r", stdin); while (scanf ("%d%d", &n, &m) == 2) {
for (int i=1; i<=n; ++i) G[i].clear ();
for (int i=1; i<=n; ++i) F[i].clear ();
for (int i=1; i<=m; ++i) {
int u, v, w; scanf ("%d%d%d", &u, &v, &w);
G[u].push_back ((Edge) {v, w});
G[v].push_back ((Edge) {u, w});
}
SPFA (1);
build_graph (); printf ("%d %d\n", Dinic (1, n), m - cnt[n]);
} return 0;
}
SPFA+Dinic HDOJ 5294 Tricks Device的更多相关文章
- HDOJ 5294 Tricks Device 最短路(记录路径)+最小割
最短路记录路径,同一时候求出最短的路径上最少要有多少条边, 然后用在最短路上的边又一次构图后求最小割. Tricks Device Time Limit: 2000/1000 MS (Java/Oth ...
- HDU 5294 Tricks Device (最大流+最短路)
题目链接:HDU 5294 Tricks Device 题意:n个点,m条边.而且一个人从1走到n仅仅会走1到n的最短路径.问至少破坏几条边使原图的最短路不存在.最多破坏几条边使原图的最短路劲仍存在 ...
- hdu 5294 Tricks Device 最短路建图+最小割
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Tricks Device Time Limit: 2000/1000 MS (Java/Other ...
- HDU 5294 Tricks Device 网络流 最短路
Tricks Device 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5294 Description Innocent Wu follows D ...
- SPFA+Dinic HDOJ 3416 Marriage Match IV
题目传送门 题意:求A到B不同最短路的条数(即边不能重复走, 点可以多次走) 分析:先从A跑最短路,再从B跑最短路,如果d(A -> u) + w (u, v) + d (B -> v) ...
- HDU 5294 Tricks Device 最短路+最大流
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5294 题意: 给你个无向图: 1.求最少删除几条边就能破坏节点1到节点n的最短路径, 2.最多能删除 ...
- hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 题意:给你n个墓室,m条路径,一个人在1号墓室(起点),另一个人在n号墓室(终点),起点的那 ...
- HDU 5294 Tricks Device(多校2015 最大流+最短路啊)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Problem Description Innocent Wu follows Dumb Zha ...
- HDU 5294 Tricks Device (最短路,最大流)
题意:给一个无向图(连通的),张在第n个点,吴在第1个点,‘吴’只能通过最短路才能到达‘张’,两个问题:(1)张最少毁掉多少条边后,吴不可到达张(2)吴在张毁掉最多多少条边后仍能到达张. 思路:注意是 ...
随机推荐
- Layui栅格系统与后台框架布局
一.栅格布局规则: 1. 采用 layui-row 来定义行,如:<div class="layui-row"></div> 2. 采用类似 layui-c ...
- Windows Socket IO 模型
http://www.cppblog.com/huangwei1024/archive/2010/11/22/134205.html
- AIM Tech R3 div2 E Centroid
思路很明显了,假设是点x,则看它的子树中是否有大于n/2的,如果有,则在该子树中剪去它可以剪的且小于n/2的,接到点x上. 则统计出在以x点为根的子树中,它的各子树可以剪去的且小于n/2的最大子子树. ...
- IntelliJ IDEA在行尾增加分号
IntelliJ IDEA在行尾增加分号 Ctrl+Shift+Enter - 本身的含义是自动完成,如果需要的话,会在行尾添加分号:
- [Java Spring] Spring Annotation Configuration Using XML
Add context to our application. main/resources/applicationContext.xml: <?xml version="1.0&qu ...
- yarn使用
参数中有中括号和尖括号,我们要识别以下区别: [] :可选项 <>:必选项 初始化一个新的项目 yarn init 添加一个依赖包 yarn add [package] yarn add ...
- pojWindow Pains(拓扑排序)
题目链接: 啊哈哈,点我点我 题意: 一快屏幕分非常多区域,区域之间能够相互覆盖,要覆盖就把属于自己的地方所有覆盖. 给出这块屏幕终于的位置.看这块屏幕是对的还是错的.. 思路: 拓扑排序,这个简化点 ...
- C++学习之构造函数中的异常处理
构造函数中可不可以抛出异常?当然可以.从语法上来说,是可以的:从实际情况来看,现在的软件系统日渐庞大和复杂,很难保证 Constructor 在执行过程中完全不发生一点异常. 那么,如果构造函数中抛出 ...
- 【code】flex_进度条样式
近期打算吧硬盘中的资料记录在博客中,实用的就当是个分享,无用的就当是个备份,还望大家不要见怪. 一共4个文件: JinDuTiaoItem.mxml: <?xml version="1 ...
- android 特殊符号开头的联系人归并至“#”下
在PeopleActivity界面.联系人的显示位置是由其display name的第一个字符决定的. 数字开头的联系人会显示在"#"这个header下. 中英文联系人会显示在&q ...