HDU 3046 Pleasant sheep and big big wolf(SAP,Dinic模板)
来源:互联网 发布:linux curl get请求 编辑:程序博客网 时间:2024/06/06 03:20
题目地址
题意:狼要吃羊,1的位置是羊的位置,2的位置是狼的位置,0是你可以放栅栏的位置,如果羊被栅栏围到了则狼就吃不掉羊了。问要用的栅栏最少是多少?
思路:让狼与源点连,羊与汇点连,可以立栅栏的位置与周围连上一条容量为1的边,这样就转化为最小割的问题了。只要源点和汇点不连通了就隔离开来了。因为是模板题,我用了两种方法写。
Dinic:
#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 50000#define M 1000000#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1000000007;int head[N], level[N];int n, m, cnt;struct node { int to; int cap;//剩余流量 int next;}edge[2 * M];int mapp[210][210];int dir[4][2] = { { 1,0 },{ 0,1 },{ -1,0 },{ 0,-1 } };bool check(int x, int y) {// 判断是否越界 if (x >= 0 && x < n && y >= 0 && y < m) return true; return false;}struct Dinic { void init() { memset(head, -1, sizeof(head)); cnt = 0; } void add(int u, int v, int cap) {//有向图 edge[cnt].to = v, edge[cnt].cap = cap, edge[cnt].next = head[u], head[u] = cnt++; edge[cnt].to = u, edge[cnt].cap = 0, edge[cnt].next = head[v], head[v] = cnt++;//反向边 } bool bfs(int s, int t) {//建立分层图 memset(level, -1, sizeof(level)); queue<int>q; level[s] = 0;//源点的层次最高 q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (edge[i].cap > 0 && level[v] < 0) { level[v] = level[u] + 1; q.push(v); if (v == t) { return true; } } } } return false; } int dfs(int u, int t, int num) {//找增广路 if (u == t || num == 0) {//找到了汇点返回当前的最小值,在这条路径上分别减去最小值 return num; } int ans = num; for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (edge[i].cap > 0 && level[u] < level[v]) { int d = dfs(v, t, min(num, edge[i].cap)); ans -= d; edge[i].cap -= d; edge[i ^ 1].cap += d;//反向边加值 if (ans == 0)return num; } } return num - ans; } int dinic(int s, int t) {//源点和汇点 int sum = 0, num; while (bfs(s, t)) { sum += dfs(s, t, inf); } return sum; }}DC;int main() { cin.sync_with_stdio(false); int Case = 1; while (cin >> n >> m) { DC.init(); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> mapp[i][j]; } } int s = n*m; int t = n*m + 1; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { int pos = i*m + j; if (mapp[i][j] == 1) { DC.add(pos, t, inf); } else if (mapp[i][j] == 2) { DC.add(s, pos, inf); } for (int k = 0; k < 4; k++) { int x = i + dir[k][0]; int y = j + dir[k][1]; if (check(x, y)) { DC.add(pos, x*m + y, 1); } } } } cout << "Case " << Case++ << ":" << endl; cout << DC.dinic(s, t) << endl; } return 0;}
SAP:
#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 40010#define M 800010#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1000000007;int mapp[210][210];int head[N];int n, m, cnt;struct node { int to; int cap;//剩余流量 int next;}edge[2 * M];//因为加了正反两条边,所以要乘二bool vis[N];int len[N];int gap[N];int pre[N];int curedge[N];int dir[4][2] = { { 1,0 },{ 0,1 },{ -1,0 },{ 0,-1 } };bool check(int x, int y) {// 判断是否越界 if (x >= 0 && x < n && y >= 0 && y < m) return true; return false;}struct Sap { void init() { memset(head, -1, sizeof(head)); cnt = 0; } void add(int u, int v, int cap) {//有向图 edge[cnt].to = v, edge[cnt].cap = cap, edge[cnt].next = head[u], head[u] = cnt++; edge[cnt].to = u, edge[cnt].cap = 0, edge[cnt].next = head[v], head[v] = cnt++;//反向边 } int max_flow(int s, int t, int n){//n为总点数个数 int cur_flow = 0, flow_ans = 0, i, u, neck, tmp; memset(len, 0, sizeof(len)); memset(gap, 0, sizeof(gap)); memset(pre, -1, sizeof(pre)); for (i = 0; i <= n; i++) curedge[i] = head[i]; gap[0] = n + 1; u = s; while (len[s] < n + 1) { if (u == t) { cur_flow = inf; for (i = s; i != t; i = edge[curedge[i]].to) { if (cur_flow > edge[curedge[i]].cap) cur_flow = edge[curedge[i]].cap, neck = i; } for (i = s; i != t; i = edge[curedge[i]].to) { tmp = curedge[i]; edge[tmp].cap -= cur_flow; edge[tmp ^ 1].cap += cur_flow; } flow_ans += cur_flow; u = neck; } for (i = curedge[u]; i != -1; i = edge[i].next) if (edge[i].cap&&len[u] == len[edge[i].to] + 1) break; if (i != -1) { curedge[u] = i; pre[edge[i].to] = u; u = edge[i].to; } else { if (0 == --gap[len[u]]) break; curedge[u] = head[u]; for (tmp = n + 5, i = head[u]; i != -1; i = edge[i].next) if (edge[i].cap) tmp = min(tmp, len[edge[i].to]); len[u] = tmp + 1; ++gap[len[u]]; if (u != s) u = pre[u]; } } return flow_ans; }}sap;int main() { cin.sync_with_stdio(false); int Case = 1; while (cin >> n >> m) { sap.init(); for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cin >> mapp[i][j]; } } int s = n*m; int t = n*m + 1; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { int pos = i*m + j; if (mapp[i][j] == 1) { sap.add(pos, t, inf); } else if (mapp[i][j] == 2) { sap.add(s, pos, inf); } for (int k = 0; k < 4; k++) { int x = i + dir[k][0]; int y = j + dir[k][1]; if (check(x, y)) { sap.add(pos, x*m + y, 1); } } } } cout << "Case " << Case++ << ":" << endl; cout<< sap.max_flow(s, t, t) << endl; } return 0;}
阅读全文
0 0
- HDU 3046 Pleasant sheep and big big wolf(SAP,Dinic模板)
- HDU 3046 Pleasant sheep and big big wolf(最小割-Dinic)
- hdu 3046 Pleasant sheep and big big wolf(sap最大流)
- hdu 3046 Pleasant sheep and big big wolf【最大流Dinic--------最小割】
- hdu 3046 Pleasant sheep and big big wolf //最小割
- hdu 3046 Pleasant sheep and big big wolf
- HDU 3046——Pleasant sheep and big big wolf
- hdu 3046 Pleasant sheep and big big wolf (最小割)
- HDU 3046 Pleasant sheep and big big wolf
- hdu 3046 Pleasant sheep and big big wolf 网络流
- hdu 3046 Pleasant sheep and big big wolf(最小割)
- HDU 3046 Pleasant sheep and big big wolf 最小割
- HDU 3046 Pleasant sheep and big big wolf | 最小割
- hdu 3046 Pleasant sheep and big big wolf 最小割
- Pleasant sheep and big big wolf (hdu 3046 最小割)
- HDU - 3046 Pleasant sheep and big big wolf(最小割)
- hdu 3046 Pleasant sheep and big big wolf(最小割)
- [Hdu 3046]Pleasant sheep and big big wolf
- Atitit 常见每日流程日程日常工作.docx v8 verampmimp 签到amy 天气情况检查amy 晨会,每天或者隔天am 每日计划(项目计划,日计划等。am
- 【LeetCode】645. Set Mismatch
- Struts2工作原理与Struts2工作流程
- ubuntu 配置java环境变量 修改/etc/environment 导致,登录界面进不去了
- Atitit.月度计划日程表 每月流程表v5
- HDU 3046 Pleasant sheep and big big wolf(SAP,Dinic模板)
- 卓美业网拓软件内测(第一波)初体验
- MySQL管理之道_ 性能调优、高可用与监控(第2版)-by 贺春畅-读书笔记
- 后台菜单
- Android IPC之 Messenger
- Windows下Android Studio长时间停留在Building "Project Name" Gradle project info画面的解决方法
- JavaScript严格模式与非严格模式之间的区别
- 使用filter(过滤器)按照条件查询hbase
- centos6.5在dell poweredge t30 安装,网络未连接的问题