Ural 1277 Cops and Thieves(最小点割集/最小割)

来源:互联网 发布:对网络流行语的看法 编辑:程序博客网 时间:2024/04/30 07:03

题意:一个团伙去偷一个美术馆,警察决定在路上堵截。警察人数为k,不能在贼窝和美术馆驻扎,只能在图上其他点驻扎,而且驻扎有一个最小人数要求,问警察能否完成任务。

解法:又是最小点割集题目,每个点拆点即可,边权为给出的r[i],然后跑一遍最大流求最小割,比较一下是否小于等于k即可。

坑点,如果美术馆和贼窝是同一伙人。。。

代码如下:

#include<iostream>#include<cstdio>#include<vector>#include<queue>#include<utility>#include<stack>#include<algorithm>#include<cstring>#include<string>#include<cmath>#include<set>#include<map>using namespace std;const int maxn = 505;const int maxm = 1e5 + 5;const int INF = 0x3f3f3f3f;inline int read() {int x=0,t=1,c;while(!isdigit(c=getchar()))if(c=='-')t=-1;while(isdigit(c))x=x*10+c-'0',c=getchar();return x*t;}int head[maxn],cur[maxn],nx[maxm<<1],to[maxm<<1],flow[maxm<<1],ppp=0;struct Dinic {int dis[maxn];int s, t;long long ans;void init() {memset(head, -1, sizeof(head));ppp = 0;}void AddEdge(int u, int v, int c) {to[ppp]=v;flow[ppp]=c;nx[ppp]=head[u];head[u]=ppp++;swap(u,v);to[ppp]=v;flow[ppp]=0;nx[ppp]=head[u];head[u]=ppp++;}bool BFS() {memset(dis, -1, sizeof(dis));dis[t] = 1; queue<int> Q;Q.push(t);while(!Q.empty()) {int x = Q.front();Q.pop();for(int i = head[x]; ~i; i = nx[i]) {if(flow[i^1] && dis[to[i]] == -1) {dis[to[i]] = dis[x] + 1;Q.push(to[i]);}}}return dis[s] != -1;}int DFS(int x, int maxflow) {if(x == t || !maxflow){ans += maxflow;return maxflow;}int ret = 0, f;for(int &i = cur[x]; ~i; i = nx[i]) {if(dis[to[i]] == dis[x] - 1 && (f = DFS(to[i], min(maxflow, flow[i])))) {ret += f;flow[i] -= f;flow[i^1] += f;maxflow -= f;if(!maxflow)break;}}return ret;}long long solve(int source, int tank) {s = source;t = tank;ans = 0;while(BFS()) {memcpy(cur, head, sizeof(cur));DFS(s, INF);}return ans;}}dinic;int k, n, m, s, t;int a[maxn];int main() {#ifndef ONLINE_JUDGE//freopen("in.txt", "r", stdin);//    freopen("out.txt", "w", stdout);#endifdinic.init();scanf("%d", &k);scanf("%d%d%d%d", &n, &m, &s, &t);for(int i = 1; i <= n; i++) {scanf("%d", &a[i]);dinic.AddEdge(i * 2, i * 2 + 1, a[i]);}dinic.AddEdge(s * 2, s * 2 + 1, INF);dinic.AddEdge(t * 2, t * 2 + 1, INF);while(m--) {int u, v;scanf("%d%d", &u, &v);dinic.AddEdge(u * 2 + 1, v * 2, INF);dinic.AddEdge(v * 2 + 1, u * 2, INF);}long long ans = dinic.solve(s * 2, t * 2 + 1);//cout << ans << '\n';if(s == t)printf("NO\n");else if(ans <= k)printf("YES\n");elseprintf("NO\n");return 0;}


原创粉丝点击