原题链接:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2304
给你一个网络,其中每条边的容量是1,你可以通过调整边的方向来获得更大的流量,现在问你能获得的最大流量是多少。并且输出更改方向的边的编号。
就每条边弄成无向的,并且标记一下是否是原始边,然后跑一发Dinic即可。然后在残余网络上寻找解即可。
#include<iostream> #include<stack> #include<vector> #include<cstring> #include<string> #include<algorithm> #include<cmath> #include<cstdio> #include<queue> #define MAX_S (1<<10)+10 #define MAX_V 500 #define MAX_N MAX_V #define INF 1000009 using namespace std; struct edge { int to, cap, rev; bool isRev; bool isOri; int id; edge(int t, int c, int r, bool ir, bool io,int iid) : to(t), cap(c), rev(r), isRev(ir), isOri(io),id(iid) { } edge() { } }; template <class T> inline bool scan_d(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; //EOF while(c!=‘ -‘ &&(c<‘0‘ ||c>‘9‘ )) c=getchar(); sgn=(c==‘ -‘ )?-1:1; ret=(c==‘ -‘ )?0:(c-‘0‘ ); while(c=getchar(),c>=‘0‘ &&c<=‘9‘ ) ret=ret*10+(c-‘0‘ ); ret*=sgn; return 1; } vector<edge> G[MAX_N]; int level[MAX_V]; int iter[MAX_V]; void init(int totNode) { for (int i = 0; i <= totNode; i++) G[i].clear(); memset(level, 0, sizeof(level)); memset(iter, 0, sizeof(iter)); } void add_edge(int from,int to,int cap,bool io,int id) { G[from].push_back(edge (to, cap, G[to].size(),0,io,id)); G[to].push_back(edge (from, 0, G[from].size() - 1,1,io,id)); } void bfs(int s) { queue<int> que; memset(level, -1, sizeof(level)); level[s] = 0; que.push(s); while (!que.empty()) { int v = que.front(); que.pop(); for (int i = 0; i < G[v].size(); i++) { edge &e = G[v][i]; if (e.cap > 0 && level[e.to] < 0) { level[e.to] = level[v] + 1; que.push(e.to); } } } } int dfs(int v,int t,int f) { if (v == t)return f; for (int &i = iter[v]; i < G[v].size(); i++) { edge &e = G[v][i]; if (e.cap > 0 && level[v] < level[e.to]) { int d = dfs(e.to, t, min(f, e.cap)); if (d > 0) { e.cap -= d; G[e.to][e.rev].cap += d; return d; } } } return 0; } int max_flow(int s,int t) { int flow = 0; for (; ;) { bfs(s); if (level[t] < 0)return flow; memset(iter, 0, sizeof(iter)); int f; while ((f = dfs(s, t, INF)) > 0) { flow += f; } } } int S,T; int N,M; vector<int> ans; int main() { scanf("%d%d", &N, &M); for (int i = 0; i < M; i++) { int u, v; scanf("%d%d", &u, &v); add_edge(u, v, 1, 1, i + 1); add_edge(v, u, 1, 0, i + 1); } scanf("%d%d", &S, &T); int f = max_flow(S, T); printf("%d\n", f); for (int i = 1; i <= N; i++) for (int j = 0; j < G[i].size(); j++) if (G[i][j].isRev == 0 && G[i][j].isOri == 0 && G[i][j].cap == 0) ans.push_back(G[i][j].id); printf("%d\n", ans.size()); for (int i = 0; i < ans.size(); i++) printf("%d\n", ans[i]); return 0; }
原文:http://www.cnblogs.com/HarryGuo2012/p/4851642.html