题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5294

题意:

给你个无向图:

1、求最少删除几条边就能破坏节点1到节点n的最短路径,

2、最多能删除多少条边同时保证1到n的最短距离不变。

题解:

首先用spfa或dijcstra跑出所有最短路组成的DAG图。

用这个图跑最大流节能解决第一个问题,用这个图跑一遍bfs最短路就能解决第二个问题。

然而我在跑最大流的时候竟然把DAG图建成双向的了orz。。

代码:

#include<iostream>
#include<cstdio>
#include<vector>
#include<utility>
#include<queue>
#include<cstring>
using namespace std; const int maxn = ;
const int INF = 0x3f3f3f3f; struct Edge {
int u, v, c, f;
Edge(int u, int v, int c, int f) :u(u), v(v), c(c), f(f) {}
Edge() {}
}; struct Dinic {
int n, m, s, t;
vector<Edge> egs;
vector<int> G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn]; void init(int n) {
this->n = n;
for (int i = ; i < n; i++) G[i].clear();
egs.clear();
} void addEdge(int u, int v, int c) {
egs.push_back(Edge(u, v, c, ));
egs.push_back(Edge(v, u, , ));
m = egs.size();
G[u].push_back(m - );
G[v].push_back(m - );
}
bool bfs() {
memset(vis, , sizeof(vis));
queue<int> Q;
Q.push(s);
d[s] = ;
vis[s] = ;
while (!Q.empty()) {
int x = Q.front(); Q.pop();
for (int i = ; i < G[x].size(); i++) {
Edge& e = egs[G[x][i]];
if (!vis[e.v] && e.c>e.f) {
vis[e.v] = ;
d[e.v] = d[x] + ;
Q.push(e.v);
}
}
}
return vis[t];
}
int dfs(int x, int a) {
if (x == t || a == ) return a;
int flow = , f;
for (int& i = cur[x]; i < G[x].size(); i++) {
Edge& e = egs[G[x][i]];
if (d[x] + == d[e.v] && (f = dfs(e.v, min(a, e.c - e.f)))>) {
e.f += f;
egs[G[x][i] ^ ].f -= f;
flow += f;
a -= f;
if (a == ) break;
}
}
return flow;
}
int Maxflow(int s, int t) {
this->s = s; this->t = t;
int flow = ;
while (bfs()) {
memset(cur, , sizeof(cur));
flow += dfs(s, INF);
}
return flow;
}
}dinic; int n, m; vector<pair<int, int> > G[maxn];
vector<pair<int,int> > pre[maxn]; int inq[maxn], d[maxn];
void spfa() {
queue<int> Q;
memset(inq, , sizeof(inq));
memset(d, 0x3f, sizeof(d));
d[] = ; inq[] = ; Q.push();
while (!Q.empty()) {
int u = Q.front(); Q.pop();
inq[u] = ;
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i].first, w = G[u][i].second;
if (d[v] > d[u] + w) {
d[v] = d[u] + w;
pre[v].clear(); pre[v].push_back(make_pair(u,w));
if (!inq[v]) {
Q.push(v); inq[v] = ;
}
}
else if (d[v] == d[u] + w) {
pre[v].push_back(make_pair(u,w));
}
}
}
} int dp[maxn];
int bfs() {
memset(dp, -, sizeof(dp));
queue<int> Q;
Q.push(n - ); dp[n - ] = ;
while (!Q.empty()) {
int u = Q.front(); Q.pop();
for (int i = ; i < pre[u].size(); i++) {
int v = pre[u][i].first;
if (dp[v] == -) {
dp[v] = dp[u] + ;
Q.push(v);
}
}
}
return dp[];
} void init() {
dinic.init(n);
for (int i = ; i < n; i++) G[i].clear(),pre[i].clear();
} int main() {
while (scanf("%d%d", &n, &m) == && n) {
init();
for (int i = ; i < m; i++) {
int u, v, w;
scanf("%d%d%d", &u, &v, &w); u--, v--;
G[u].push_back(make_pair(v, w));
G[v].push_back(make_pair(u, w));
}
spfa();
for (int i = n - ; i > ; i--) {
for (int j = ; j < pre[i].size(); j++) {
int v = pre[i][j].first;
//最后建出来的图应该是DAG图!
//dinic.addEdge(i, v, 1);
dinic.addEdge(v, i, );
}
}
int ans1 = dinic.Maxflow(,n-);
int ans2 = m-bfs();
printf("%d %d\n", ans1,ans2);
}
return ;
} /*
8 9
1 2 2
2 3 2
2 4 1
3 5 3
4 5 4
5 8 1
1 6 2
6 7 5
7 8 2 3 3
1 2 1
1 3 1
2 3 1 3 4
1 2 1
2 3 0
1 3 2
1 3 3 */

HDU 5294 Tricks Device 最短路+最大流的更多相关文章

  1. hdu 5294 Tricks Device 最短路建图+最小割

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Tricks Device Time Limit: 2000/1000 MS (Java/Other ...

  2. HDU 5294 Tricks Device (最大流+最短路)

    题目链接:HDU 5294 Tricks Device 题意:n个点,m条边.而且一个人从1走到n仅仅会走1到n的最短路径.问至少破坏几条边使原图的最短路不存在.最多破坏几条边使原图的最短路劲仍存在 ...

  3. HDU 5294 Tricks Device 网络流 最短路

    Tricks Device 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5294 Description Innocent Wu follows D ...

  4. HDOJ 5294 Tricks Device 最短路(记录路径)+最小割

    最短路记录路径,同一时候求出最短的路径上最少要有多少条边, 然后用在最短路上的边又一次构图后求最小割. Tricks Device Time Limit: 2000/1000 MS (Java/Oth ...

  5. HDU 5294 Tricks Device(多校2015 最大流+最短路啊)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Problem Description Innocent Wu follows Dumb Zha ...

  6. hdu 5294 Tricks Device(2015多校第一场第7题)最大流+最短路

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294   题意:给你n个墓室,m条路径,一个人在1号墓室(起点),另一个人在n号墓室(终点),起点的那 ...

  7. HDU 5294 Tricks Device (最短路,最大流)

    题意:给一个无向图(连通的),张在第n个点,吴在第1个点,‘吴’只能通过最短路才能到达‘张’,两个问题:(1)张最少毁掉多少条边后,吴不可到达张(2)吴在张毁掉最多多少条边后仍能到达张. 思路:注意是 ...

  8. SPFA+Dinic HDOJ 5294 Tricks Device

    题目传送门 /* 题意:一无向图,问至少要割掉几条边破坏最短路,问最多能割掉几条边还能保持最短路 SPFA+Dinic:SPFA求最短路时,用cnt[i]记录到i最少要几条边,第二个答案是m - cn ...

  9. Tricks Device (hdu 5294 最短路+最大流)

    Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) To ...

随机推荐

  1. (五)、nodejs使用bootstrap的样式进行分页

    一.page方法 /****************************************************** * Created User: * Created Time: 201 ...

  2. VBA表格单元格替换文字

    Sub 表格单元格替换文字() If MsgBox("确定要替换单元格的文字吗?", vbYesNo + vbQuestion) = vbYes Then To ActiveDoc ...

  3. [leetcode]_Reverse Integer

    经历了三道树的题后,完全崩溃中,急需一道非树图的题来挽救信心. 题目:反转数字.input : 123 , output : 321. 思路:直接,没什么好说的. 自己代码:很龊,有大量的冗余信息,还 ...

  4. jquery easyui combobox

    $("#select_Dic").combobox({                        url: "http://www.cnblogs.com/Ajax/ ...

  5. 学习c语言的第9天

    #include <stdio.h> int main() { float sum=0,wage=0; int i=1; int num; printf("+++平均工资统计程序 ...

  6. 十天学会单片机Day4串行口通信

    并行与串行基本通信方式 1.并行通信方式 通常是将数据字节的各位用多条数据线同时进行传送. 并行通信控制简单.传输速度快:由于传输线较多,长距离传送时成本高且接收方的各位同时接收存在困难. 2.串行通 ...

  7. linux网络子系统内核分析

    1.选择路由 若要将数据包发至PC2,则linux系统通过查询路由表可知168.1.1.10(目的地址)的网关地址为192.168.1.1,此时linux系统选择网卡1发送数据包. 2.邻居子系统(通 ...

  8. linux回环网卡驱动设计

    回环网卡驱动 1.回环网卡和普通网卡的区别是他是虚拟的不是实际的物理网卡,它相当于把普通网卡的发送端和接收端短接在一起. 2.在内核源代码里的回环网卡程序(drivers/net/loopback.c ...

  9. IOS开发之后台处理

    1 前言IOS4 之后提供了后台处理,在后台运行应用程序,在一些情形下甚至可以在用户按下Home按钮之后在后台运行. 2 详述IOS可以在用户按下Home按钮后将应用程序添加到暂停状态.这种暂停执行的 ...

  10. 推荐一个sqlce,sqllite等数据库管理工具

    推荐一个sqlce,sqllite等数据库管理工具 下载地址: http://fishcodelib.com/files/DatabaseNet4.zip 支持sqlserver,sqlce, sql ...