http://acm.hdu.edu.cn/showproblem.php?pid=3046

题意:

给出矩阵地图和羊和狼的位置,求至少需要建多少栅栏,使得狼不能到达羊。

思路:
狼和羊不能到达,最小割最大流问题。

因为狼和羊都有多只,所以我们加一个超级源点和一个超级汇点,将每只狼与超级源点相连,容量为INF,将每只羊与超级汇点相连,容量为INF。对于地图上的点,每个点都与它上下左右相连,容量设为1。

接下来,我们只需要计算出从超级源点到超级汇点的最大流,因为最小割等于最大流。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#include<queue>
using namespace std; const int maxn = *;
const int INF = 0x3f3f3f3f; struct Edge
{
int from,to, cap, flow;
Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){}
}; int n, m,t;
vector<Edge> edges;
vector<int> G[maxn];
int vis[maxn];
int d[maxn]; //从起点到i的距离
int cur[maxn]; //当前弧下标
int flow; void init()
{
for (int i = ; i < maxn; i++)
G[i].clear();
edges.clear();
} void AddEdge(int from, int to, int cap)
{
edges.push_back(Edge(from, to, cap, ));
edges.push_back(Edge(to, from, , ));
int m = edges.size();
G[from].push_back(m - );
G[to].push_back(m - );
} int BFS()
{
memset(vis, , sizeof(vis));
queue<int> Q;
Q.push();
d[] = ;
vis[] = ;
while (!Q.empty())
{
int x = Q.front();
Q.pop();
for (int i = ; i < G[x].size(); i++)
{
Edge& e = edges[G[x][i]];
if (!vis[e.to] && e.cap>e.flow)
{
vis[e.to] = ;
d[e.to] = d[x] + ;
Q.push(e.to);
}
}
}
return vis[n*m + ];
} int DFS(int x,int a)
{
if (x == n*m + || a == ) return a;
int flow = , f;
for (int& i = cur[x]; i < G[x].size(); i++)
{
Edge& e = edges[G[x][i]];
if (d[x] + == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow)))>)
{
e.flow += f;
edges[G[x][i] ^ ].flow -= f;
flow += f;
a -= f;
if (a == ) break;
}
}
return flow;
} void Maxflow(int s,int t)
{
flow = ;
while (BFS())
{
memset(cur, , sizeof(cur));
flow += DFS(s, INF);
}
} int main()
{
//freopen("D:\\txt.txt", "r", stdin);
int kase = ;
int a;
while (~scanf("%d%d", &n, &m))
{
init();
for (int i = ; i <= n;i++)
for (int j = ; j <= m; j++)
{
if (i != )
AddEdge((i - )*m + j, (i-)*m+j, );
if (i != n)
AddEdge((i - )*m + j, i*m + j, );
if (j != )
AddEdge((i - )*m + j, (i - )*m + j - , );
if (j != m)
AddEdge((i - )*m + j, (i - )*m + j + , );
scanf("%d", &a);
if (a == )
AddEdge(, (i - )*m + j, INF);
else if (a == )
AddEdge((i - )*m + j, m*n + , INF);
}
Maxflow(, n*m + );
printf("Case %d:\n%d\n", ++kase, flow);
}
}

HDU 3046 Pleasant sheep and big wolf(最小割最大流+Dinic)的更多相关文章

  1. HDU 3046 Pleasant sheep and big big wolf(最小割)

    HDU 3046 Pleasant sheep and big big wolf 题目链接 题意:一个n * m平面上,1是羊.2是狼,问最少要多少围墙才干把狼所有围住,每有到达羊的路径 思路:有羊和 ...

  2. hdu 3046 Pleasant sheep and big big wolf 最小割

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3046 In ZJNU, there is a well-known prairie. And it a ...

  3. HDU 3046 Pleasant sheep and big big wolf

    Pleasant sheep and big big wolf Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged ...

  4. UVa 1660 电视网络(点连通度+最小割最大流+Dinic)

    https://vjudge.net/problem/UVA-1660 题意:给出一个无向图,求出点连通度.即最少删除多少个点,使得图不连通. 思路: 如果求线连通度的话,直接求个最大流就可以了.但这 ...

  5. hdu4289 最小割最大流 (拆点最大流)

    最小割最大流定理:(参考刘汝佳p369)增广路算法结束时,令已标号结点(a[u]>0的结点)集合为S,其他结点集合为T=V-S,则(S,T)是图的s-t最小割. Problem Descript ...

  6. 【BZOJ-1797】Mincut 最小割 最大流 + Tarjan + 缩点

    1797: [Ahoi2009]Mincut 最小割 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1685  Solved: 724[Submit] ...

  7. BZOJ-1001 狼抓兔子 (最小割-最大流)平面图转对偶图+SPFA

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 14686 Solved: 3513 [Submit][ ...

  8. hdu1569 方格取数(2) 最大点权独立集=总权和-最小点权覆盖集 (最小点权覆盖集=最小割=最大流)

    /** 转自:http://blog.csdn.net/u011498819/article/details/20772147 题目:hdu1569 方格取数(2) 链接:https://vjudge ...

  9. BZOJ1001:狼抓兔子(最小割最大流+vector模板)

    1001: [BeiJing2006]狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨, ...

随机推荐

  1. vue.set的用法

    Vue.set(this.food,'count',1) //就是给this.food里面添加一个count的属性,并且赋值为1

  2. [py模块]random&string取随机字符串

    栗子 - 取n位的随机字符串(大小写/数字) def get_random_str(len_str): import string import random letters_nums = strin ...

  3. PIMPL(一)

    1 参考 <effective C++> 条款31:将文件间的编译关系降至最低 PIMPL Idiom: http://c2.com/cgi/wiki?PimplIdiom 2 什么是PI ...

  4. ftp.GetResponse() 无法连接到远程服务器

    最近在做一个ftp上传下载以及在服务器上创建文件夹的工具 报 GetResponse() 无法连接到远程服务器  错误 明明 ip , 账户和 密码 用ftp 工具都能连接上 ,可是 代码就不行了,看 ...

  5. c#获取指定时区的日期

    1.首先将服务器的时间转化为utc时间,然后转换成指定时区的日期 public DateTime GetSpecificZoneNowDate(string zoneName = "Chin ...

  6. windows中xcopy命令详解

    一.格式: 二.举例说明: 1.复制文件,文件路径有空格的,那么就使用双引号括起来.如果目标路径已经有相同文件了,使用覆盖方式而不进行提示.在复制文件的同时也复制空目录或子目录      xcopy  ...

  7. vue数据双向绑定原理

    vue的数据双向绑定的小例子: .html <!DOCTYPE html> <html> <head> <meta charset=utf-> < ...

  8. uva 13598

    /* 题目的大意是 给你 N 学生 然后 给前 K个学生编号了 给定的 号码 , 然后你按照 使得接下来学生 学号尽量小的 方法 从第 K+1个学生开始编号 每个号码 自然只能用一次, 解答 : 先将 ...

  9. python getatime() 查看文件的访问时间

    import time,os def main(): file_name=r'C:\Temp\Req.xml' file_times_access=time.localtime(os.path.get ...

  10. python excel操作单元格复制和读取的两种方法

    操作单元格 新建一个sheet, 单元格赋值(两种方法) 单元格A1赋值为’xiaxiaoxu’ 单元格A2赋值为‘xufengchai’ 打印A1和A2单元格的值(两种方法) #coding=utf ...