POJ1273Drainage Ditches(网络最大流裸题)
ISAP + 邻接矩阵
// Nero
// 邻接矩阵
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define FOR(i,a,b) for(int i=(a); i<=(b); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
#define clr(a,b) memset(a,b,sizeof(a))
const int INF = ~0u>>1;
const int MAXN = 210;
int g[MAXN][MAXN];
int gap[MAXN],dis[MAXN],pre[MAXN],cur[MAXN];
int n;
int Isap(int s, int t, int nodenum) {
clr(gap,0); clr(dis,0); clr(cur,0);
int u = pre[s] = s, maxflow = 0, aug = INF;
gap[0] = nodenum;
while(dis[s] < nodenum) {
loop: FOR(v,cur[u],nodenum) if(g[u][v] && dis[u] == dis[v] + 1) {
aug = min(aug,g[u][v]);
pre[v] = u;
u = cur[u] = v;
if(v == t) {
maxflow += aug;
for(u = pre[u]; v != s; v = u, u = pre[u]) {
g[u][v] -= aug;
g[v][u] += aug;
}
aug = INF;
}
goto loop;
}
int mindis = nodenum - 1;
FOR(v,0,nodenum) if(g[u][v] && mindis > dis[v]) {
cur[u] = v;
mindis = dis[v];
}
if((--gap[dis[u]]) == 0) break;
gap[dis[u] = mindis+1] ++;
u = pre[u];
}
return maxflow;
}
int main() {
int m;
while(~scanf("%d%d", &m, &n)) {
clr(g,0);
int a,b,c;
while(m--) {
scanf("%d%d%d", &a, &b, &c);
g[a][b] += c;
}
printf("%d\n", Isap(1,n,n));
}
return 0;
}
ISAP + 邻接表
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int MAXN=10100;
const int INF = ~0u>>1;
#define clr(a,b) memset(a,b,sizeof(a))
#define FOR(i,a,b) for(int i=(a); i<=(b); i++)
#define REP(i,a,b) for(int i=(a); i<(b); i++)
struct EDGE
{
int v,c,next;
}edge[101000];
int E,head[MAXN];
int gap[MAXN], cur[MAXN], pre[MAXN], dis[MAXN];
void add_edge(int s,int t,int c,int cc = 0)
{
edge[E].v=t; edge[E].c=c;
edge[E].next=head[s]; head[s]=E++;
edge[E].v=s; edge[E].c=cc;
edge[E].next=head[t]; head[t]=E++;
}
int min(int a,int b){return (a==-1||b<a)?b:a;}
int SAP(int s,int t,int n)
{
memset(gap,0,sizeof(gap));
memset(dis,0,sizeof(dis));
int i;
for(i=0;i<n;i++)cur[i]=head[i];
int u=pre[s]=s,maxflow=0,aug=-1,v;
gap[0]=n;
while(dis[s]<n)
{
loop: for(i=cur[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(edge[i].c>0&&dis[u]==dis[v]+1)
{
aug=min(aug,edge[i].c);
pre[v]=u;
cur[u]=i;
u=v;
if(u==t)
{
for(u=pre[u];v!=s;v=u,u=pre[u])
{
edge[cur[u]].c-=aug;
edge[cur[u]^1].c+=aug;
}
maxflow+=aug;
aug=-1;
}
goto loop;
}
}
int mindis=n;
for(i=head[u];i!=-1;i=edge[i].next)
{
v=edge[i].v;
if(edge[i].c>0&&dis[v]<mindis)
{
cur[u]=i;
mindis=dis[v];
}
}
if((--gap[dis[u]])==0)break;
gap[dis[u]=mindis+1]++;
u=pre[u];
}
return maxflow;
}
int main() {
int n,m;
while(~scanf("%d%d", &m, &n)) {
E = 0;
clr(head, -1);
int a,b,c;
REP(i,0,m) {
scanf("%d%d%d", &a, &b, &c);
add_edge(a,b,c);
}
printf("%d\n", SAP(1,n,n+1));
}
return 0;
}
最大流Dinic算法
/* Created Time: Tuesday, November 12, 2013 PM10:48:24 CST */
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int M = 555;
const int N = 222;
const int INF = 0x3f3f3f3f;
struct edge {
int v,cap,next;
}g[M<<1];
int level[N]; // 顶点到源点的距离标号
int iter[N]; // 当前弧,在其之前的边已经没有用了
int n,m,head[N],etot;
void add_edge(int u,int v,int w) {
g[etot].v = v; g[etot].cap = w;
g[etot].next = head[u]; head[u] = etot ++;
g[etot].v = u; g[etot].cap = 0;
g[etot].next = head[v]; head[v] = etot ++;
}
int que[N],qf,qe;
void bfs(int s) {
memset(level,-1,sizeof(level));
qf = 0,qe = -1;
level[s] = 0;
que[++qe] = s;
while (qf<=qe) {
int u = que[qf++];
for (int i = head[u]; i != -1; i = g[i].next) {
int v = g[i].v;
int cap = g[i].cap;
if (cap>0 && level[v]<0) {
level[v] = level[u]+1;
que[++qe] = v;
}
}
}
}
int dfs(int u,int t,int f) {
if (u==t) return f;
if (iter[u]==-1) iter[u] = head[u];
for (int &i = iter[u]; i != -1; i = g[i].next) {
int v = g[i].v;
int cap = g[i].cap;
if (cap>0 && level[u]<level[v]) {
int d = dfs(v,t,min(f,cap));
if (d>0) {
g[i].cap -= d;
g[i^1].cap += d;
return d;
}
}
}
return 0;
}
int Dinic(int s,int t) {
int flow = 0;
for (;;) {
bfs(s);
if (level[t]<0) return flow;
memset(iter,-1,sizeof(iter));
int f;
while ((f=dfs(s,t,INF))>0)
flow += f;
}
}
int main() {
while (~scanf("%d%d",&m,&n)) {
etot = 0;
for (int i = 0; i <= n; i ++)
head[i] = -1;
for (int i = 0; i < m; i ++) {
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add_edge(a,b,c);
}
printf("%d\n",Dinic(1,n));
}
return 0;
}