看了这道题,然后重新开始练习自己的刚敲不久的网络流,发现还是难以一遍敲得完整啊,,,,,

调了。。。遍,改了。。。遍,测了。。。遍,交了,,,遍,总算是A了,,不简单啊

然后试着用了其他两种算法EK和dinic都试着去练习一下,慢慢A了,,,真是不简单有木有

题目大意是这样的,有一些小偷打算从城市S到城市T,但是我们不知道他们会走哪些边,为了确保一定可以能够抓住所有的小偷,现在需要在某些城市布置一些警察,已知在城市i布置的花费是P[i],现在要使的抓住小偷的同时我的花费最小,求最小花费。

这里用到了最大流的一个定理,最小割最大流定理:当起点到终点的最大流算出来时,这个最大流就是将图划分为两个互不连通的集合的最小割。证明可以自己百度或看其他神牛的博客。

有了这个定理,就变成了裸的最大流问题了

下面我试着用三种方法做了这道题,比较了一下发现最快的依然是SAP,其次是dinic,最后是EK算法

SAP

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf ((LL)1<<40)
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FOPENIN(IN) freopen(IN, "r", stdin)
#define FOPENOUT(OUT) freopen(OUT, "w", stdout)
template<class T> T ABS ( T a) { return a >= ? a : -a; }
template<class T> T CMP_MIN ( T a, T b ) { return a < b; }
template<class T> T CMP_MAX ( T a, T b ) { return a > b; }
template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b; }
template<class T> void SWAP( T& a, T& b ) { T t = a; a = b; b = t; } typedef __int64 LL;
//typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
const double PI = 4.0 * atan(1.0);
const LL MOD = ; #define L(i) (i<<1)
#define R(i) (i<<1|1) int m, n, s, d;
struct Edge { int to, cap, next; }edge[MAXM<<];
int tot, head[MAXN]; int src, des;
int gap[MAXN], dep[MAXN], aug[MAXN], cur[MAXN], pre[MAXN]; void addEdge(int u, int v, int c)
{
edge[tot].to = v; edge[tot].cap = c; edge[tot].next = head[u];
head[u] = tot ++;
edge[tot].to = u; edge[tot].cap = ; edge[tot].next = head[v];
head[v] = tot ++;
} void init()
{
int x, y;
tot = ;
mem1(head); mem0(edge);
scanf("%d %d", &s, &d);
for(int i = ; i <= n; i ++)
{
scanf("%d", &x);
addEdge(L(i), R(i), x);
addEdge(R(i), L(i), x);
}
for(int i = ; i < m; i ++)
{
scanf("%d %d", &x, &y);
addEdge(R(x), L(y), INF);
addEdge(R(y), L(x), INF);
}
src = ;
des = (n+)<<;
addEdge(src, L(s), INF);
addEdge(R(d), des, INF);
} int SAP(int n)
{
mem0(gap);
mem0(dep);
mem0(aug);
mem0(pre);
aug[src] = INF;
pre[src] = -;
gap[] = n;
int max_flow = , u = src;
for(int i = ; i <= n; i ++)
cur[i] = head[i];
while(dep[src] < n)
{
if(u == des)
{
max_flow += aug[des];
for(int v = pre[des]; v != -; v = pre[v])
{
int id = cur[v];
edge[id].cap -= aug[des];
edge[id^].cap += aug[des];
aug[v] -= aug[des];
if(edge[id].cap == )
u = v;
}
}
int flag = ;
for(int i = cur[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > && dep[u] == dep[v]+)
{
flag = ;
pre[v]= u;
cur[u] = i;
aug[v] = MIN(aug[u], edge[i].cap);
u = v;
break;
}
}
if(!flag)
{
if(--gap[dep[u]] == )
break;
int min_dep = n;
cur[u] = head[u];
for(int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(edge[i].cap > && dep[v] < min_dep)
{
min_dep = dep[v];
cur[u] = i;
}
}
dep[u] = min_dep + ;
gap[dep[u]] ++;
if(pre[u] != -) u = pre[u];
}
}
return max_flow;
} int main()
{
while(~scanf("%d %d", &n, &m))
{
init();
printf("%d\n", SAP(des));
}
return ;
}

dinic

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf ((LL)1<<40)
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FOPENIN(IN) freopen(IN, "r", stdin)
#define FOPENOUT(OUT) freopen(OUT, "w", stdout)
template<class T> T ABS ( T a) { return a >= ? a : -a; }
template<class T> T CMP_MIN ( T a, T b ) { return a < b; }
template<class T> T CMP_MAX ( T a, T b ) { return a > b; }
template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b; }
template<class T> void SWAP( T& a, T& b ) { T t = a; a = b; b = t; } typedef __int64 LL;
//typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
const double PI = 4.0 * atan(1.0);
const LL MOD = ; #define L(i) (i<<1)
#define R(i) (i<<1|1) int m, n, s, d;
struct Edge { int to, cap, next; }edge[MAXM<<];
int tot, head[MAXN]; int src, des;
int dis[MAXN]; void addEdge(int u, int v, int c)
{
edge[tot].to = v; edge[tot].cap = c; edge[tot].next = head[u];
head[u] = tot ++;
edge[tot].to = u; edge[tot].cap = ; edge[tot].next = head[v];
head[v] = tot ++;
} void init()
{
int x, y;
tot = ;
mem1(head); mem0(edge);
scanf("%d %d", &s, &d);
for(int i = ; i <= n; i ++)
{
scanf("%d", &x);
addEdge(L(i), R(i), x);
addEdge(R(i), L(i), x);
}
for(int i = ; i < m; i ++)
{
scanf("%d %d", &x, &y);
addEdge(R(x), L(y), INF);
addEdge(R(y), L(x), INF);
}
src = ;
des = (n+)<<;
addEdge(src, L(s), INF);
addEdge(R(d), des, INF);
} bool bfs()
{
queue<int>q;
mem1(dis);
dis[src] = ;
q.push(src);
while(!q.empty())
{
int u = q.front(); q.pop();
for(int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if(dis[v] == - && edge[i].cap > )
{
dis[v] = dis[u] + ;
q.push(v);
}
}
}
return dis[des] != -;
} int dfs(int cur, int aug)
{
if(cur == des || aug == )
return aug;
int flow = ;
for(int i = head[cur]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if ( dis[v] == dis[cur]+ && edge[i].cap > )
{
int f = dfs( v, MIN(edge[i].cap, aug) );
edge[i].cap -= f;
edge[i^].cap += f;
flow += f;
aug -= f;
if(aug == )
break;
}
}
return flow;
} int dinic()
{
int res = ;
while (bfs())
{
res += dfs(src, INF);
}
return res;
} int main()
{
//FOPENIN("in.txt");
while(~scanf("%d %d", &n, &m))
{
init();
printf("%d\n", dinic());
}
return ;
}

EK

 #include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define inf ((LL)1<<40)
#define lson k<<1, L, mid
#define rson k<<1|1, mid+1, R
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define mem(a, b) memset(a, b, sizeof(a))
#define FOPENIN(IN) freopen(IN, "r", stdin)
#define FOPENOUT(OUT) freopen(OUT, "w", stdout)
template<class T> T ABS ( T a) { return a >= ? a : -a; }
template<class T> T CMP_MIN ( T a, T b ) { return a < b; }
template<class T> T CMP_MAX ( T a, T b ) { return a > b; }
template<class T> T MAX ( T a, T b ) { return a > b ? a : b; }
template<class T> T MIN ( T a, T b ) { return a < b ? a : b; }
template<class T> T GCD ( T a, T b ) { return b ? GCD ( b, a % b ) : a; }
template<class T> T LCM ( T a, T b ) { return a / GCD ( a, b ) * b; }
template<class T> void SWAP( T& a, T& b ) { T t = a; a = b; b = t; } typedef __int64 LL;
//typedef long long LL;
const int MAXN = ;
const int MAXM = ;
const double eps = 1e-;
const double PI = 4.0 * atan(1.0);
const LL MOD = ; #define L(i) (i<<1)
#define R(i) (i<<1|1) int n, m, s, d; int src, des;
int cap[MAXN][MAXN], flow[MAXN][MAXN], pre[MAXN], a[MAXN]; void init()
{
int x, y;
src = ;
des = (n+)<<;
mem0(cap);mem0(pre);
scanf("%d %d", &s, &d);
cap[src][L(s)] = INF;
cap[R(d)][des] = INF;
for(int i = ; i <= n; i ++)
{
scanf("%d", &x);
cap[L(i)][R(i)] = x;
cap[R(i)][L(i)] = x;
}
for(int i = ; i < m; i ++)
{
scanf("%d %d", &x, &y);
cap[R(x)][L(y)] = INF;
cap[R(y)][L(x)] = INF;
}
} int EK(int n)
{
queue<int>q;
mem0(flow);
int max_flow = ;
while(true)
{
mem0(a);
a[src] = INF;
q.push(src);
while(!q.empty())
{
int u = q.front(); q.pop();
for(int v = ; v <= n; v ++) if(!a[v] && cap[u][v]>flow[u][v])
{
pre[v]= u;
q.push(v);
a[v] = MIN(a[u], cap[u][v] - flow[u][v]);
}
}
if(a[des] == ) break;
for(int u = des; u != src; u = pre[u])
{
flow[pre[u]][u] += a[des];
flow[u][pre[u]] -= a[des];
}
max_flow += a[des];
}
return max_flow;
} int main()
{
//FOPENIN("in.txt");
while(~scanf("%d %d", &n, &m))
{
init();
printf("%d\n", EK(des));
}
return ;
}

HDU4289Control(最大流)的更多相关文章

  1. HDU4289Control 无向图拆点最大流

    /* ** 无向图拆点,求最大流,最大流即为割点个数. */ #include <iostream> #include <cstdio> #include <cstrin ...

  2. 使用C#处理基于比特流的数据

    使用C#处理基于比特流的数据 0x00 起因 最近需要处理一些基于比特流的数据,计算机处理数据一般都是以byte(8bit)为单位的,使用BinaryReader读取的数据也是如此,即使读取bool型 ...

  3. HTML 事件(三) 事件流与事件委托

    本篇主要介绍HTML DOM中的事件流和事件委托. 其他事件文章 1. HTML 事件(一) 事件的介绍 2. HTML 事件(二) 事件的注册与注销 3. HTML 事件(三) 事件流与事件委托 4 ...

  4. FILE文件流的中fopen、fread、fseek、fclose的使用

    FILE文件流用于对文件的快速操作,主要的操作函数有fopen.fseek.fread.fclose,在对文件结构比较清楚时使用这几个函数会比较快捷的得到文件中具体位置的数据,提取对我们有用的信息,满 ...

  5. java.IO输入输出流:过滤流:buffer流和data流

    java.io使用了适配器模式装饰模式等设计模式来解决字符流的套接和输入输出问题. 字节流只能一次处理一个字节,为了更方便的操作数据,便加入了套接流. 问题引入:缓冲流为什么比普通的文件字节流效率高? ...

  6. java 字节流与字符流的区别

    字节流与和字符流的使用非常相似,两者除了操作代码上的不同之外,是否还有其他的不同呢?实际上字节流在操作时本身不会用到缓冲区(内存),是文件本身直接操作的,而字符流在操作时使用了缓冲区,通过缓冲区再操作 ...

  7. BZOJ 3504: [Cqoi2014]危桥 [最大流]

    3504: [Cqoi2014]危桥 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1407  Solved: 703[Submit][Status] ...

  8. java I/O流

    输入流(读取数据的流) BufferedInputStream---继承--->FileInputStream--继承--->InputStream------> (1)字节流操作中 ...

  9. Ford-Fulkerson 最大流算法

    流网络(Flow Networks)指的是一个有向图 G = (V, E),其中每条边 (u, v) ∈ E 均有一非负容量 c(u, v) ≥ 0.如果 (u, v) ∉ E 则可以规定 c(u, ...

随机推荐

  1. Openerp上传中文名附件,下载时报错的处理方法

    文档管理中,如果上传的文件名含有中文字符,下载时会提示出错,如没有权限等.这个问题困惑我比较久的时间,通过跟踪openerp_server.log,可以看到类似提示: 2012-09-28 21:51 ...

  2. HDU Sky数 2097

    解题思路:类比求出10进制数各个位上的数字之和,求出12进制和16进制上的数. #include<cstdio> #include<cstring> #include<a ...

  3. Eclipse实用快捷键

    经典常用快捷键1. [ALT+/]此快捷键为用户编辑的好帮手,能为用户提供内容的辅助,不要为记不全方法和属性名称犯愁,当记不全类.方法和属性的名字时,多体验一下[ALT+/]快捷键带来的好处吧. 2. ...

  4. Http中Cookie与Set-Cookie头

    [原文:http://hi.baidu.com/qinglvzhuye/item/6664a807bb8be3dd73e676d6] android 获取 cookies 有很多办法,但是记住了. h ...

  5. 包装类-Character

    1,isDigit();是否是数字 char c = '1'; boolean bool = Character.isDigit(c); System.out.println(bool);//true ...

  6. C++ STL算法系列5---equal() , mismatch()

    equal和mismatch算法的功能是比较容器中的两个区间内的元素.这两个算法各有3个参数first1,last1和first2.如果对 于区间[first1,last1)内所有的first1+i, ...

  7. A+B for Matrices 及 C++ transform的用法

    题目大意:给定两个矩阵,矩阵的最大大小是M*N(小于等于10),矩阵元素的值的绝对值小于等于100,求矩阵相加后全0的行以及列数. #include<iostream> using nam ...

  8. free-jqGrid

    PM> Install-Package free-jqGrid jqGrid 是一个用来显示网格数据的jQuery插件,通过使用jqGrid可以轻松实现前端页面与后台数据的ajax异步通信.文档 ...

  9. loadrunner下检查点乱码情况处理

    对于很多用过LR的人来说,乱码一直是很纠结的事情,尤其是对新手来说.网上给的解决方法是在录制的时候勾选UTF-8选项,但是似乎并没有解决. 对于用户名为中文或者检查点为中文的情况,我们又该如何去处理呢 ...

  10. Android百度地图开发(三)范围搜索

    // 1.新建项目 将地图API添加进classpath中: 2.在activity_main.xml中添加一个MapView,用来显示地图: <LinearLayout xmlns:andro ...