ural 1277. Cops and Thieves【最小割】
来源:互联网 发布:ubuntu php sqlite3 编辑:程序博客网 时间:2024/04/30 04:04
ural 1277. Cops and Thieves【最小割】
分类: 【图论专辑】2010-07-28 00:00 210人阅读 评论(2) 收藏 举报
/* 小偷要从S城市到T城市偷东西,每个城市需要不同数量的警察来看守,现在给出警察数量,看能不能成功阻止小偷
* 题意即是求最小割,但是由于给出的是每个点的容量,所以需要将每个点拆为两个点,之间连边,容量为点的容量,
* 两个城市如果相连则容量置为无穷大。然后求最大流看是否大于已有警察数。拆点的时候可以将点i拆为2*i-1和2*i
* 这个题最后一组数据源点和汇点是一个点,很变态,需要特别考虑。。。@@
*/
- #include <cstdio>
- #include <cstring>
- #define FOR(a,b) for(int i = a; i<= b; ++i)
- #define INF 0x1f1f1f1f
- #define MAXN 250
- using namespace std;
- int n,m,src,sink,num;
- int cap[MAXN][MAXN],f[MAXN][MAXN],level[MAXN],q[MAXN];
- inline bool dinic_bfs(){
- int queue[MAXN];
- memset(level,-1,sizeof(level));
- int head = 0,tail = 0;
- queue[tail++] = src;
- level[src] = 0;
- while(tail > head){
- int tep = queue[head++];
- for(int i = 1;i <= n; ++i){
- if(level[i] == -1 && cap[tep][i] > f[tep][i]){
- level[i] = level[tep] + 1;
- queue[tail++] = i;
- }
- }
- }
- return level[sink] != -1;
- }
- inline int dinic(){
- int cur,k,m,tail,maxflow = 0, *stack = q;
- while(dinic_bfs()){
- tail = 0;
- stack[tail++] = src;
- while(tail){
- cur = stack[tail-1];
- if(cur == sink){
- m = INF;
- for(int i = 1;i < tail; ++i){
- if(m > cap[stack[i-1]][stack[i]]-f[stack[i-1]][stack[i]]){
- m = cap[stack[i-1]][stack[i]]-f[stack[i-1]][stack[i]];
- k = i;
- }
- }
- maxflow += m;
- for(int i = 1;i < tail; ++i){
- f[stack[i-1]][stack[i]] += m;
- f[stack[i]][stack[i-1]] -= m;
- }
- tail = k;
- }
- else{
- int i;
- for(i = 1;i <= n; ++i){
- if(level[i] == level[cur] + 1 && cap[cur][i] > f[cur][i]){
- stack[tail++] = i;
- break;
- }
- }
- if(i == n+1){
- level[cur] = -1;
- --tail;
- }
- }
- }
- }
- return maxflow;
- }
- int main()
- {
- while(scanf("%d",&num) != EOF){
- int k;
- scanf("%d%d%d%d",&n,&m,&src,&sink);
- memset(cap,0,sizeof(cap));
- memset(f,0,sizeof(f));
- for(int i = 1;i <= n; ++i){
- scanf("%d",&k);
- cap[2*i-1][2*i] = k; // 将一个点拆为两个点,容量为点的容量
- cap[2*i][2*i-1] = k;
- }
- while(m--){
- int u,v;
- scanf("%d%d",&u,&v);
- cap[2*u][2*v-1] = INF;
- cap[2*v][2*u-1] = INF;
- }
- n = 2*n; src = 2*src; sink = 2*sink - 1;
- int ans = dinic();
- if(ans > num || sink+1 == src)//如果最大流大于警察数或者源点汇点是一个点
- printf("NO/n");
- else printf("YES/n");
- }
- }
- ural 1277. Cops and Thieves【最小割】
- ural 1277. Cops and Thieves【最小割】
- URAL 1277 Cops and Thieves 最小割
- Ural 1277 Cops and Thieves(最小点割集/最小割)
- Ural 1277 - Cops and Thieves 无向图的最小点割
- Ural 1277 cops ans thieves (最小割模型)
- Thieves----简单最小割
- HDU 3491 Thieves | 最小割
- hdu 3491 Thieves 最小割
- hdu 3491 Thieves(最小割)
- HDU 3491 Thieves 拆点 最小割
- hdoj 3491 Thieves 【最小割 + 拆点】
- Thieves (hdu 3491 拆点 最小割)
- uva 1277 Cops and Thieves(完成阻击所需要的最少人数)
- URAL 1851|GOV-internship|最小割
- URAL 1277 网络流最小割 解题报告
- UVA 361 Cops and Robbers
- UVa 361 - Cops and Robbers
- UVALive 3882 And Then There Was One
- 六个变态的Hello World!(混乱代码)
- jquery的DOM操作
- 一位ACMer过来人的心得
- phonegap 实现摇一摇
- ural 1277. Cops and Thieves【最小割】
- USB协议的基本概念
- uva 10970 Big Chocolate
- tpcc mysql 基准测试
- scp命令的用法详解
- 产品、设计、项目管理、开发、以及部署和运帷的第三方工具
- 单例模式应用
- X264使用介绍
- java面试题杂记