标签:最大流 match ble nbsp nic isp 代码 == show
题意:现在有n城市,m条单向路,现在男生在A城市,女生在B城市,现在男生要从A -> B 去看女生,每条路只能走一次,并且男生很懒,他第一次走的是A -> B的最短路,以后每次走的路都不能超过这个,求
男生从A->B次数最多有多少次。
题解:就是求有多少个不相干的最短路径数,我们正向跑一遍spfa 跑出最短路,再反向跑一边跑出最短路, 对于一条边来说,如果 dis1[u] + dis2[v] + w = dis1[t] 那么这条边就是构成最短路的一条边,我们把这个边加入网络流中,最后跑出最大流就是结果了。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); 4 #define LL long long 5 #define ULL unsigned LL 6 #define fi first 7 #define se second 8 #define pb push_back 9 #define lson l,m,rt<<1 10 #define rson m+1,r,rt<<1|1 11 #define lch(x) tr[x].son[0] 12 #define rch(x) tr[x].son[1] 13 #define max3(a,b,c) max(a,max(b,c)) 14 #define min3(a,b,c) min(a,min(b,c)) 15 typedef pair<int,int> pll; 16 const int inf = 0x3f3f3f3f; 17 const LL INF = 0x3f3f3f3f3f3f3f3f; 18 const LL mod = (int)1e9 + 7; 19 const int N = 2000; 20 const int M = 1000000; 21 int head[N], deep[N], cur[N]; 22 int w[M], to[M], nx[M]; 23 int tot; 24 void add(int u, int v, int val){ 25 w[tot] = val; to[tot] = v; 26 nx[tot] = head[u]; head[u] = tot++; 27 28 w[tot] = 0; to[tot] = u; 29 nx[tot] = head[v]; head[v] = tot++; 30 } 31 int bfs(int s, int t){ 32 queue<int> q; 33 memset(deep, 0, sizeof(deep)); 34 q.push(s); 35 deep[s] = 1; 36 while(!q.empty()){ 37 int u = q.front(); 38 q.pop(); 39 for(int i = head[u]; ~i; i = nx[i]){ 40 if(w[i] > 0 && deep[to[i]] == 0){ 41 deep[to[i]] = deep[u] + 1; 42 q.push(to[i]); 43 } 44 } 45 } 46 return deep[t] > 0; 47 } 48 int Dfs(int u, int t, int flow){ 49 if(u == t) return flow; 50 for(int &i = cur[u]; ~i; i = nx[i]){ 51 if(deep[u]+1 == deep[to[i]] && w[i] > 0){ 52 int di = Dfs(to[i], t, min(w[i], flow)); 53 if(di > 0){ 54 w[i] -= di, w[i^1] += di; 55 return di; 56 } 57 } 58 } 59 return 0; 60 } 61 62 int Dinic(int s, int t){ 63 int ans = 0, tmp; 64 while(bfs(s, t)){ 65 for(int i = 0; i <= t; i++) cur[i] = head[i]; 66 while(tmp = Dfs(s, t, inf)) ans += tmp; 67 } 68 return ans; 69 } 70 71 void init(){ 72 memset(head, -1, sizeof(head)); 73 tot = 0; 74 } 75 struct Node{ 76 int to; 77 int w; 78 int op; 79 }; 80 vector<Node> e[N]; 81 int dis1[N], dis2[N], vis[N]; 82 void spfa(int s, int t, int dd[], int op){ 83 dd[s] = 0; 84 queue<int> q; 85 q.push(s); 86 vis[s] = 1; 87 while(!q.empty()){ 88 int u = q.front(); 89 vis[u] = 0; 90 q.pop(); 91 for(int i = 0; i < e[u].size(); i++){ 92 if(e[u][i].op != op) continue; 93 if(dd[u] + e[u][i].w < dd[e[u][i].to]){ 94 dd[e[u][i].to] = dd[u] + e[u][i].w; 95 if(!vis[e[u][i].to]) { 96 vis[e[u][i].to] = 1; 97 q.push(e[u][i].to); 98 } 99 } 100 } 101 } 102 103 } 104 int main(){ 105 int T, n, m, u, v, dis; 106 scanf("%d", &T); 107 while(T--){ 108 scanf("%d%d", &n, &m); 109 for(int i = 1; i <= n; i++) e[i].clear(); 110 for(int i = 1; i <= m; i++){ 111 scanf("%d%d%d", &u, &v, &dis); 112 e[u].pb({v, dis, 1}); 113 e[v].pb({u, dis, 2}); 114 } 115 int a, b; 116 scanf("%d%d", &a, &b); 117 memset(dis1, inf, sizeof(dis1)); 118 spfa(a, b, dis1, 1); 119 memset(dis2, inf, sizeof(dis2)); 120 spfa(b, a, dis2, 2); 121 init(); 122 int s = 0, t = n + 1; 123 for(int i = 1; i <= n; i++) 124 for(int j = 0; j < e[i].size(); j++){ 125 int v = e[i][j].to, w = e[i][j].w; 126 if(dis1[i] + w + dis2[v] == dis1[b] && e[i][j].op == 1){ 127 add(i,v,1); 128 } 129 } 130 add(s, a, inf); 131 add(b, t, inf); 132 printf("%d\n",Dinic(s,t)); 133 } 134 return 0; 135 }
标签:最大流 match ble nbsp nic isp 代码 == show
原文地址:https://www.cnblogs.com/MingSD/p/9739250.html