avatar
fireworks99
keep hungry keep foolish

HDU 3416 Marriage IV(the shortest path and maxflow)

Description

求最短路有几种方案

(不同的两种方案所经过的边完全不同!)

Analyze

以 A 为起点跑一遍spfa, 得到 dis_a[]

以 B 为起点跑一遍spfa, 得到 dis_b[]

对于边(u, v, w),若满足dis_a[u] + dis_b[v] + w == dis_a[B]

则这条边是最短路的可选边(可以作为最短路上的一条边)

找出所有的可选边,设其容量为1,A到B的最大流即完全不同的最短路方案数

结论:图论相关的题目,求有几种方案:将确定边设容量为1,求最大流即可

Code

#include <queue> #include <stack> #include <vector> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define Begin cout << "Check Begin---------------\n"; #define END cout << "Check End-----------------\n"; #define Exit cout << "Exit---------------------\n"; const int INF = 0x3f3f3f3f; const int N = int(1e3) + 5; const int M = int(1e5) + 5; int n, m, start, over; int cnt_a, cnt_b, cnt_c; struct edge { int to, w, pre; } a[M], b[M], c[2 * M]; int dis_a[N], dis_b[N]; bool vis_a[N], vis_b[N]; int head_a[N], head_b[N], head_c[N]; void init() { cnt_a = 0, cnt_b = 0, cnt_c = 0; for(int i = 0; i <= n; ++i) { dis_a[i] = dis_b[i] = INF; vis_a[i] = vis_b[i] = 0; head_a[i] = head_b[i] = head_c[i] = -1; } } void add(int & cnt, edge * e, int * head, int from, int to, int w) { e[cnt].to = to; e[cnt].w = w; e[cnt].pre = head[from]; head[from] = cnt++; } void spfa(int s, int * head, edge * e, int * dis, bool * vis) { queue<int> q; q.push(s); dis[s] = 0; vis[s] = 1; while(!q.empty()) { int now = q.front(); q.pop(); vis[now] = 0; for(int i = head[now]; ~i; i = e[i].pre) { int to = e[i].to; if(dis[to] > dis[now] + e[i].w) { dis[to] = dis[now] + e[i].w; if(!vis[to]) q.push(to), vis[to] = 1; } } } } int maxflow, deep[N], cur[N]; bool BFS(int s, int t) { memset(deep, INF, sizeof(deep)); for(int i = 0; i <= n; ++i) cur[i] = head_c[i]; deep[s] = 0; queue<int> q; q.push(s); while(!q.empty()) { int now = q.front(); q.pop(); for(int i = head_c[now]; ~i; i = c[i].pre) if(deep[ c[i].to ] == INF && c[i].w) { deep[ c[i].to ] = deep[now] + 1; q.push(c[i].to); } } if(deep[t] < INF) return 1; return 0; } int DFS(int now, int t, int limit) { if(!limit || now == t) return limit; int flow = 0, f; for(int i = cur[now]; ~i; i = c[i].pre) { cur[now] = i;///Try To Realize this sentence!!! if(deep[ c[i].to ] == deep[now] + 1) if(f = DFS(c[i].to, t, min(limit, c[i].w))) { flow += f; limit -= f; c[i].w -= f; c[i ^ 1].w += f; if(!limit) break; } } return flow; } void Dinic(int s, int t) { int tem; while(BFS(s, t)) while(tem = DFS(s, t, INF)) maxflow += tem; } int main() { int _; scanf("%d", &_); while(_--) { scanf("%d %d", &n, &m); init(); int u[M], v[M], w[M]; for(int i = 1; i <= m ; ++i) { scanf("%d %d %d", &u[i], &v[i], &w[i]); if(u[i] == v[i]) continue; add(cnt_a, a, head_a, u[i], v[i], w[i]); add(cnt_b, b, head_b, v[i], u[i], w[i]); } scanf("%d %d", &start, &over); spfa(start, head_a, a, dis_a, vis_a); spfa(over, head_b, b, dis_b, vis_b); for(int i = 1; i <= m; ++i) if(u[i] != v[i] && dis_a[ u[i] ] + dis_b[ v[i] ] + w[i] == dis_a[over]) { add(cnt_c, c, head_c, u[i], v[i], 1); add(cnt_c, c, head_c, v[i], u[i], 0); } maxflow = 0; Dinic(start, over); cout << maxflow << '\n'; } return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166

注意形参里的引用与指针的合理使用!

Site by Baole Zhao | Powered by Hexo | theme PreciousJoy