hdu4289 Control最小割

来源:互联网 发布:mac全角半角切换 编辑:程序博客网 时间:2024/05/21 08:16

<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        :2016File 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_backtypedef 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        :2016File 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_backtypedef 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;}


0 0