<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">一个城市交通图,上面有n个城市,m条双通道路,现在有个间谍要从s逃到t去,想要抓住他,但是只能在城市里面抓,不能在公路上,通过监控城市来实现抓捕,监控每个城市需要一定的费用,只要在所监控的城市出现了这个间谍就能抓住他,问抓住间谍的最小费用。</span>
就是不能让间谍到达t,可以转换成s到t的最小割,将城市拆点,容量为监控费用。
/***************************************** Author :Crazy_AC(JamesQi) Time :2016 File Name :最小割==最大流。 *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; typedef pair<ii,int> iii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 500; const int maxm = 100000; int head[maxn], cap[maxm], flow[maxm], pnt[maxm], nxt[maxm]; int ecnt; inline void Addedge(int u,int v,int c) { pnt[ecnt] = v, nxt[ecnt] = head[u], cap[ecnt] = c; flow[ecnt] = 0, head[u] = ecnt++; pnt[ecnt] = u, nxt[ecnt] = head[v], cap[ecnt] = 0; flow[ecnt] = 0, head[v] = ecnt++; } int s, t; int dis[maxn]; bool spfa() { queue<int> que; memset(dis, -1,sizeof dis); dis[s] = 0; que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); // cout << u << ' '; for (int i = head[u];i != -1;i = nxt[i]) { int v = pnt[i]; if (cap[i] > flow[i] && dis[v] == -1) { dis[v] = dis[u] + 1; que.push(v); } } } // cout << endl; return dis[t] != -1; } int dfs(int u,int a) { if (u == t || a == 0) return a; int ret = 0,f; for (int i = head[u];i != -1;i = nxt[i]) { int v = pnt[i]; if (dis[v] > dis[u] && (f = dfs(v, min(a, cap[i] - flow[i]))) > 0) { ret += f; a -= f; flow[i] += f; flow[i^1] -= f; if (a == 0) break; } } return ret; } int MaxFlow() { int ret = 0; while(spfa()) { // cout << "here\n"; ret += dfs(s, INF); } return ret; } int n, m; int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(~scanf("%d%d",&n,&m)) { s = 0,t = n*2 + 1; int u, v, c; scanf("%d%d",&u,&v); memset(head, -1,sizeof head); ecnt = 0; Addedge(s, u, INF); Addedge(v + n, t, INF); for (int i = 1;i <= n;++i) { scanf("%d",&c); Addedge(i,i+n,c); } for (int i = 1;i <= m;++i) { scanf("%d%d",&u,&v); Addedge(u+n, v, INF); Addedge(v+n, u, INF); } printf("%d\n", MaxFlow()); } return 0; }
/***************************************** Author :Crazy_AC(JamesQi) Time :2016 File Name :ISAP *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; typedef pair<ii,int> iii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 500; struct Edge{ int from, to, cap, flow; Edge(){} Edge(int from,int to,int cap,int flow) :from(from),to(to),cap(cap),flow(flow){ } }; struct ISAP{ int n, m, s, t; bool vis[maxn]; int cur[maxn], num[maxn], dis[maxn], pre[maxn]; vector<Edge>edges; vector<int>G[maxn]; void init(int n) { this->n = n; for (int i = 0;i <= n;++i) { G[i].clear(); dis[i] = INF; } edges.clear(); } void addedge(int u,int v,int c) { edges.push_back(Edge(u, v, c, 0)); edges.push_back(Edge(v, u, 0, 0)); m = (int)edges.size(); G[u].push_back(m-2); G[v].push_back(m-1); } bool bfs() { memset(vis, false,sizeof vis); queue<int> que; que.push(t); dis[t] = 0; vis[t] = true; while(!que.empty()) { int u = que.front(); que.pop(); for (int i = 0;i < G[u].size();++i) { Edge& e = edges[G[u][i]^1]; if (e.cap > e.flow && !vis[e.from]) { vis[e.from] = true; dis[e.from] = dis[u] + 1; que.push(e.from); } } } return vis[s]; } int Augment() { int u = t, flow = INF; while(u != s) { Edge& e = edges[pre[u]]; flow = min(flow, e.cap - e.flow); u = edges[pre[u]].from; } u = t; while(u != s) { edges[pre[u]].flow += flow; edges[pre[u]^1].flow -= flow; u = edges[pre[u]].from; } return flow; } int MaxFlow(int s,int t) { this->s = s, this->t = t; int ret = 0; bfs(); if (dis[s] >= n) return 0; memset(num, 0,sizeof num); memset(cur, 0,sizeof cur); for (int i = 0;i < n;++i) { if (dis[i] < INF) num[dis[i]]++; } int u = s; while(dis[s] < n) { if (u == t) { ret += Augment(); u = s; } bool ok = false; for (int i = cur[u];i < G[u].size();++i) { Edge& e = edges[G[u][i]]; if (e.cap > e.flow && dis[u] == dis[e.to] + 1) { ok = true; pre[e.to] = G[u][i]; cur[u] = i; u = e.to; break; } } if (!ok) { int Min = n - 1; for (int i = 0;i < G[u].size();++i) { Edge& e = edges[G[u][i]]; if (e.cap > e.flow ) Min = min(Min, dis[e.to]); } if (--num[dis[u]] == 0) break; num[dis[u] = Min + 1]++; cur[u] = 0; if (u != s) u = edges[pre[u]].from; } } return ret; } }; ISAP isap; int n, m; int s, t; int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(~scanf("%d%d",&n,&m)) { s = 0,t = n * 2 + 1; isap.init(t+1); int u, v, c; scanf("%d%d",&u,&v); isap.addedge(s, u, INF); isap.addedge(v + n, t, INF); for (int i = 1;i <= n;++i) { scanf("%d",&c); isap.addedge(i,i+n,c); } for (int i = 1;i <= m;++i) { scanf("%d%d",&u,&v); isap.addedge(u+n,v,INF); isap.addedge(v+n,u,INF); } printf("%d\n", isap.MaxFlow(s, t)); } return 0; }