Marriage Match IV HDU - 3416
2017-07-29 20:12
309 查看
题意
给你n个点,m条边,要求每条边只能走一次的S到T的最短路径的个数题解
在我又WA又TLE还RE时,yyb大佬告诉我说要跑两遍SPFA,还说我写的一遍SPFA是错的,然而啪啪打脸。。。
而且他的
比我跑得慢,2333
接下来讲一下方法
首先一遍SPFA(或dijkstra)从S跑一遍到所有点的最短路,重新建图时对于每对u, v 若 dis[u] + w[u][v] == dis[v] 则加入这条边,容量为1(还要加反边),最后跑最大流即可,最大流我用的是Dinic,然后注意手打队列,系统的会TLE
常熟巨大的丑陋代码
# include <bits/stdc++.h> # define RG register # define IL inline # define ll long long # define mem(a, b) memset(a, b, sizeof(a)) # define Min(a, b) (((a) > (b)) ? (b) : (a)) # define Max(a, b) (((a) < (b)) ? (b) : (a)) using namespace std; IL int Get(){ RG char c = '!'; RG int x = 0, z = 1; for(; c > '9' || c < '0'; c = getchar()) z = c == '-' ? -1 : 1; for(; c <= '9' && c >= '0'; c = getchar()) x = x * 10 + c - '0'; return x * z; } const int MAXN = 1001, MAXM = 200001, INF = 2147483647; int n, m, ft[MAXN], cnt, ans, dis[MAXN], vis[MAXN], _ft[MAXN], level[MAXN], Q[MAXM]; struct Edge{ int to, f, nt; } edge[MAXM], _edge[MAXM]; IL void Add(RG int u, RG int v, RG int f){ edge[cnt] = (Edge){v, f, ft[u]}; ft[u] = cnt++; } IL void Add2(RG int u, RG int v, RG int f){ _edge[cnt] = (Edge){v, f, _ft[u]}; _ft[u] = cnt++; } IL void SPFA(RG int S, RG int T){ RG int head = 0, tail = 0; Q[0] = S; vis[S] = 1; dis[S] = 0; while(head <= tail){ RG int u = Q[head++]; vis[u] = 0; for(RG int e = ft[u]; e != -1; e = edge[e].nt){ RG int v = edge[e].to, f = edge[e].f + dis[u]; if(dis[v] > f){ dis[v] = f; if(!vis[v]) vis[v] = 1, Q[++tail] = v; } } } } IL bool Bfs(RG int S, RG int T){ mem(level, 0); RG int head = 0, tail = 0; Q[0] = S; level[S] = 1; while(head <= tail){ RG int u = Q[head++]; if(u == T) return 1; for(RG int e = _ft[u]; e != -1; e = _edge[e].nt){ RG int v = _edge[e].to, f = _edge[e].f; if(f && !level[v]){ level[v] = level[u] + 1; Q[++tail] = v; } } } return 0; } IL int Dfs(RG int u, RG int T, RG int maxf){ if(u == T) return maxf; RG int res = 0; for(RG int e = _ft[u]; e != -1; e = _edge[e].nt){ RG int v = _edge[e].to, f = _edge[e].f; if(level[u] + 1 == level[v] && f){ f = Dfs(v, T, Min(f, maxf - res)); _edge[e].f -= f; _edge[e ^ 1].f += f; res += f; if(res == maxf) break; } } return res; } int main(){ RG int T = Get(); while(T--){ n = Get(); m = Get(); mem(ft, -1); mem(dis, 63); mem(_ft, -1); ans = cnt = 0; for(RG int i = 1; i <= m; i++){ RG int u = Get(), v = Get(), f = Get(); if(u == v) continue; Add(u, v, f); } RG int S = Get(), T = Get(); cnt = 0; SPFA(S, T); for(RG int i = 1; i <= n; i++) for(RG int e = ft[i]; e != -1; e = edge[e].nt) if(dis[i] + edge[e].f == dis[edge[e].to]) Add2(i, edge[e].to, 1), Add2(edge[e].to, i, 0); while(Bfs(S, T)) ans += Dfs(S, T, INF); printf("%d\n", ans); } return 0; }
相关文章推荐
- HDU 3416 Marriage Match IV(中等,好题) [最大流]最短路+最大流
- hdu 3416 Marriage Match IV
- HDU 3416 Marriage Match IV
- HDU 3416 Marriage Match IV
- hdu 3416 Marriage Match IV dijkstra + isap
- HDU 3416 Marriage Match IV
- Marriage Match IV HDU - 3416
- HDU 3416 Marriage Match IV
- HDU 3416 Marriage Match IV
- Marriage Match IV HDU - 3416
- hdu 3416 Marriage Match IV
- HDU 3416 Marriage Match IV
- Marriage Match IV (hdu 3416 网络流+spfa最短路)
- 【HDOJ】3416 Marriage Match IV
- SPFA+Dinic HDOJ 3416 Marriage Match IV
- 3416 Marriage Match IV
- hdu 3416 Marriage Match IV 【网络最大流+最短路】
- HDU 3416 Marriage Match IV (最短路判断建边+最大流)
- [HDU 3416]Marriage Match IV[最大流][最短路]
- HDU ~ 3416 ~ Marriage Match IV (最短路Dijkstra + 网络流Dinic)