标签:
#pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #include<string.h> #include<queue> #include<stack> #include<vector> using namespace std; const int MAXN = 1e6+7; const int MAXM = 1005; const int oo = 1e9+7; ///分别存正向图,反向图,和重构图 struct Edge{int v, val, next;}ss[MAXN], ee[MAXN], edge[MAXN<<1]; int Hs[MAXM], He[MAXM], Head[MAXM], cnt_s, cnt_e, cnt; int DistS[MAXM], DistE[MAXM];///分别是从源点到达每点的距离,和每点到达源点的距离 int Layer[MAXM];///分层 void InIt(int N) { cnt = cnt_e = cnt_s = 0; memset(Hs, -1, sizeof(Hs)); memset(He, -1, sizeof(He)); memset(Head, -1, sizeof(Head)); for(int i=1; i<=N; i++) DistE[i] = DistS[i] = oo; } void AddEdge(Edge e[], int head[], int &ct, int u, int v, int val) { e[ct].v = v; e[ct].val = val; e[ct].next = head[u]; head[u] = ct++; } void spfa(Edge e[], int head[], int dist[], int start) {///求最短路 stack<int> sta; bool instack[MAXM] = {0}; dist[start] = 0; sta.push(start); while(sta.size()) { int u = sta.top();sta.pop(); instack[u] = false; for(int j=head[u]; j!=-1; j=e[j].next) { int v = e[j].v; if(dist[v] > dist[u]+e[j].val) { dist[v] = dist[u] + e[j].val; if(instack[v] == false) { instack[v] = true; sta.push(v); } } } } } void BuildGraph(int u, int MinLen) {///遍历所有的边,把输入最短路的边加入新图中 for(int j=Hs[u]; j!=-1; j=ss[j].next) { int v = ss[j].v; if(v != -1) { if(DistS[u] + DistE[v] + ss[j].val == MinLen) { AddEdge(edge, Head, cnt, u, v, 1); AddEdge(edge, Head, cnt, v, u, 0); } ss[j].v = -1; BuildGraph(v, MinLen); } } } bool BFS(int start, int End) { memset(Layer, 0, sizeof(Layer)); Layer[start] = 1; queue<int> Q; Q.push(start); while(Q.size()) { int u = Q.front();Q.pop(); if(u == End)return true; for(int j=Head[u]; j!=-1; j=edge[j].next) { int v = edge[j].v; if(Layer[v] == false && edge[j].val) { Layer[v] = Layer[u] + 1; Q.push(v); } } } return false; } int DFS(int u, int MaxFlow, int End) { if(u == End)return MaxFlow; int uflow = 0; for(int j=Head[u]; j!=-1; j=edge[j].next) { int v = edge[j].v; if(Layer[u]+1 == Layer[v] && edge[j].val) { int flow = min(MaxFlow-uflow, edge[j].val); flow = DFS(v, flow, End); edge[j].val -= flow; edge[j^1].val += flow; uflow += flow; if(uflow == MaxFlow) break; } } if(uflow == 0) Layer[u] = 0; return uflow; } int Dinic(int start, int End) { int MaxFlow = 0; while(BFS(start, End) == true) MaxFlow += DFS(start, oo, End); return MaxFlow; } int main() { int T; scanf("%d", &T); while(T--) { int N, M, u, v, val; scanf("%d%d", &N, &M); InIt(N); while(M--) { scanf("%d%d%d", &u, &v, &val); if(u == v)continue; AddEdge(ss, Hs, cnt_s, u, v, val); AddEdge(ee, He, cnt_e, v, u, val); } int start, End; scanf("%d%d", &start, &End); spfa(ss, Hs, DistS, start);///求源点到所有点的距离 spfa(ee, He, DistE, End);///求所有点到汇点的最短距离 BuildGraph(start, DistS[End]);///构建新图 printf("%d\n", Dinic(start, End)); } return 0; }
O - Marriage Match IV - hdu 3416(最短路+最大流)
标签:
原文地址:http://www.cnblogs.com/liuxin13/p/4728490.html