POJ 1273 简单BFS网络流模板
#include<stdio.h>
#include <queue>
#include<string.h>
using namespace std;
int g[300][300];
int Prev[300];
bool visited[300];
int n, m;
unsigned augment()
{
queue<int> q;
memset(Prev, 0, sizeof(Prev));
memset(visited, 0, sizeof(visited));
Prev[1] = 0;
visited[1] = 1;
q.push(1);
bool isFindPath = false;
int v;
while (!q.empty())
{
v = q.front();
q.pop();
for (int i = 1; i <= m; i++)
{
if (g[v][i]>0 && visited[i] == 0)
{
Prev[i] = v;
visited[i] = 1;
if (i == m)
{
isFindPath = true;
while (!q.empty())
q.pop();
break;
}
else
q.push(i);
}
}
}
if (isFindPath == false)
return 0;
int nMinFlow = 1 << 30;
v = m;
while (Prev[v])
{
nMinFlow = min(nMinFlow, g[Prev[v]][v]);
v = Prev[v];
}
v = m;
while (Prev[v])
{
g[Prev[v]][v] -= nMinFlow;
g[v][Prev[v]] += nMinFlow;
v = Prev[v];
}
return nMinFlow;
}
int main()
{
while (scanf("%d%d", &n, &m) == 2)
{
int s, e, c;
memset(g, 0, sizeof(g));
for (int i = 0; i<n; i++)
{
scanf("%d%d%d", &s, &e, &c);
g[s][e] += c;
}
unsigned int maxFlow = 0;
unsigned int aug;
while (aug = augment())
maxFlow += aug;
printf("%d\n", maxFlow);
}
}
POJ 1273 Dinic模板
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<queue>
#include<ctype.h>
#include<map>
#include<math.h>
using namespace std;
#define INF 1<<30
int g[300][300];
bool visited[300];
int Layer[300];
int n, m;
bool countLayer()
{
int layer = 0;
deque<int> q;
memset(Layer, -1, sizeof(Layer));
Layer[1] = 0;
q.push_back(1);
while (!q.empty())
{
int v = q.front();
q.pop_front();
for (int j = 1; j <= m; j++)
{
if (g[v][j] > 0 && Layer[j] == -1)
{
Layer[j] = Layer[v] + 1;
if (j == m)
return true;
else
q.push_back(j);
}
}
}
return false;
}
int dinic()
{
int nMaxFlow = 0;
deque<int> q;
while (countLayer())
{
memset(visited, 0, sizeof(visited));
q.push_back(1);
visited[1] = true;
while (!q.empty())
{
int nd = q.back();
if (nd == m)
{
int nMinC = INF;
int nMinC_vs;
for (int i = 1; i < q.size(); i++)
{
int vs = q[i - 1];
int ve = q[i];
if (nMinC > g[vs][ve])
{
nMinC = g[vs][ve];
nMinC_vs = vs;
}
}
nMaxFlow += nMinC;
for (int i = 1; i < q.size(); i++)
{
int vs = q[i - 1];
int ve = q[i];
g[vs][ve] -= nMinC;
g[ve][vs] += nMinC;
}
while (!q.empty() && q.back() != nMinC_vs)
{
visited[q.back()] = 0;
q.pop_back();
}
}
else
{
int i;
for (i = 1; i <= m; i++)
{
if (g[nd][i]>0 && Layer[i] == Layer[nd] + 1 && visited[i] == false)
{
visited[i] = 1;
q.push_back(i);
break;
}
}
if (i > m)
{
q.pop_back();
}
}
}
}
return nMaxFlow;
}
int main()
{
while (scanf("%d%d", &n, &m) == 2)
{
int s, e, c;
memset(g, 0, sizeof(g));
for (int i = 0; i < n; i++)
{
scanf("%d%d%d", &s, &e, &c);
g[s][e] += c;
}
printf("%d\n", dinic());
}
}
POJ 3436 生产线最大流
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<queue>
#include<ctype.h>
#include<map>
#include<math.h>
using namespace std;
#define INF 1<<30
struct Machine
{
int q;
int in[15];
int out[15];
};
Machine input[120];
int g[120][120];
int backup_g[120][120];
bool visited[120];
int Layer[120];
int p, n;
int s, t;
bool countLayer()
{
int layer = 0;
deque<int> q;
memset(Layer, -1, sizeof(Layer));
Layer[0] = 0;
q.push_back(0);
while (!q.empty())
{
int v = q.front();
q.pop_front();
for (int j = 0; j <= t; j++)
{
if (g[v][j] > 0 && Layer[j] == -1)
{
Layer[j] = Layer[v] + 1;
if (j == t)
return true;
else
q.push_back(j);
}
}
}
return false;
}
int dinic()
{
int nMaxFlow = 0;
deque<int> q;
while (countLayer())
{
memset(visited, 0, sizeof(visited));
q.push_back(0);
visited[0] = true;
while (!q.empty())
{
int nd = q.back();
if (nd == t)
{
int nMinC = INF;
int nMinC_vs;
for (int i = 1; i < q.size(); i++)
{
int vs = q[i - 1];
int ve = q[i];
if (nMinC > g[vs][ve])
{
nMinC = g[vs][ve];
nMinC_vs = vs;
}
}
nMaxFlow += nMinC;
for (int i = 1; i < q.size(); i++)
{
int vs = q[i - 1];
int ve = q[i];
g[vs][ve] -= nMinC;
g[ve][vs] += nMinC;
}
while (!q.empty() && q.back() != nMinC_vs)
{
visited[q.back()] = 0;
q.pop_back();
}
}
else
{
int i;
for (i = 0; i <= t; i++)
{
if (g[nd][i]>0 && Layer[i] == Layer[nd] + 1 && visited[i] == false)
{
visited[i] = 1;
q.push_back(i);
break;
}
}
if (i > t)
{
q.pop_back();
}
}
}
}
return nMaxFlow;
}
struct Ans
{
int a;
int b;
int w;
};
int main()
{
while (scanf("%d%d", &p, &n) == 2)
{
s = 0;
t = 2 * n + 1;
memset(g, 0, sizeof(g));
for (int i = 1; i <= n; i++)
{
scanf("%d", &input[i].q);
int flag = 1;
for (int j = 0; j < p; j++)
{
scanf("%d", &input[i].in[j]);
if (input[i].in[j] == 1)
{
flag = 0;
}
}
if (flag)
g[0][i] = INF;
flag = 1;
for (int j = 0; j < p; j++)
{
scanf("%d", &input[i].out[j]);
if (input[i].out[j] != 1)
flag = 0;
}
if (flag)
{
g[n + i][t] = INF;
}
g[i][n + i] = input[i].q;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i == j)
continue;
int tag = 1;
for (int k = 0; k < p; k++)
{
if (input[j].in[k] != 2 && input[i].out[k] != input[j].in[k])
{
tag = 0;
break;
}
}
if (tag)
{
g[n + i][j] = INF;
}
}
}
memcpy(backup_g, g, sizeof(g));
int maxFlow = dinic();
int cnt = 0;
vector<Ans > ans;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i == j)
continue;
if (g[n + i][j] < backup_g[n + i][j])
{
cnt++;
Ans a;
a.a = i;
a.b = j;
a.w = backup_g[n + i][j] - g[n + i][j];
ans.push_back(a);
}
}
}
printf("%d %d\n", maxFlow, cnt);
for (int i = 0; i < ans.size(); i++)
{
printf("%d %d %d\n", ans[i].a, ans[i].b, ans[i].w);
}
}
}
POJ 2112 奶牛挤奶
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string>
#include<queue>
#include<ctype.h>
#include<map>
#include<math.h>
using namespace std;
#define INF 0x3f3f3f3f
int k, c, m;
int dist[250][250];
int g[250][250];
bool visited[250];
int Layer[250];
int s, t;
bool countLayer()
{
int layer = 0;
deque<int> q;
memset(Layer, -1, sizeof(Layer));
Layer[0] = 0;
q.push_back(0);
while (!q.empty())
{
int v = q.front();
q.pop_front();
for (int j = 0; j <= t; j++)
{
if (g[v][j] > 0 && Layer[j] == -1)
{
Layer[j] = Layer[v] + 1;
if(j==t)
return true;
else
q.push_back(j);
}
}
}
return false;
}
int dinic()
{
int nMaxFlow = 0;
deque<int> q;
while (countLayer())
{
memset(visited, 0, sizeof(visited));
q.push_back(0);
visited[0] = true;
while (!q.empty())
{
int nd = q.back();
if (nd == t)
{
int nMinC = INF;
int nMinC_vs;
for (int i = 1; i < q.size(); i++)
{
int vs = q[i - 1];
int ve = q[i];
if (nMinC > g[vs][ve])
{
nMinC = g[vs][ve];
nMinC_vs = vs;
}
}
nMaxFlow += nMinC;
for (int i = 1; i < q.size(); i++)
{
int vs = q[i - 1];
int ve = q[i];
g[vs][ve] -= nMinC;
g[ve][vs] += nMinC;
}
while (!q.empty() && q.back() != nMinC_vs)
{
visited[q.back()] = 0;
q.pop_back();
}
}
else
{
int i;
for (i = 0; i <= t; i++)
{
if (g[nd][i]>0 && Layer[i] == Layer[nd] + 1 && visited[i] == false)
{
visited[i] = 1;
q.push_back(i);
break;
}
}
if (i > t)
{
q.pop_back();
}
}
}
}
return nMaxFlow;
}
void build_map(int dis)
{
memset(g, 0, sizeof(g));
s = 0;
t = k + c + 1;
for (int i = 1; i <= k; ++i)
g[0][i] = m;
for (int i = k + 1; i <= k + c; ++i)
g[i][t] = 1;
for (int i = 1; i <= k; ++i)
for (int j = k + 1; j <= k + c; ++j)
if (dist[i][j] <= dis)
g[i][j] = 1;
}
int main()
{
while (scanf("%d%d%d", &k, &c, &m)==3)
{
s = 0;
t = k + c + 1;
for (int i = 1; i <= k + c; i++)
{
for (int j = 1; j <= k + c; j++)
{
scanf("%d", &dist[i][j]);
if (dist[i][j] == 0)
dist[i][j] = INF;
}
}
for (int kk = 1; kk <= k + c; kk++)
{
for (int i = 1; i <= k + c; i++)
{
for (int j = 1; j <= k + c; j++)
{
dist[i][j] = min(dist[i][j], dist[i][kk] + dist[kk][j]);
}
}
}
int low = 1, high = INF;
int maxFlow;
int ans;
while (low <= high)
{
int mid = (low + high) / 2;
build_map(mid);
maxFlow = dinic();
if (maxFlow == c)
{
high = mid - 1;
ans = mid;
}
else
{
low = mid + 1;
}
}
printf("%d\n", ans);
}
}
POJ 2396 最大流填充方格
#include<iostream>
#include<string>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cstdio>
using namespace std;
const int MAXN = 255;
const int INF = 0x3f3f3f3f;
int g[MAXN][MAXN], flow[MAXN][MAXN], low[MAXN][MAXN], high[MAXN][MAXN];
int rSum[MAXN], cSum[MAXN], Layer[MAXN];
bool visited[MAXN];
int m, n;
int s, t;
int ss, tt;
bool countLayer(int startP, int endP)
{
int layer = 0;
deque<int> q;
memset(Layer, -1, sizeof(Layer));
Layer[startP] = 0;
q.push_back(startP);
while (!q.empty())
{
int v = q.front();
q.pop_front();
for (int j = 0; j <= endP; j++)
{
if (g[v][j] > 0 && Layer[j] == -1)
{
Layer[j] = Layer[v] + 1;
if (j == endP)
return true;
else
q.push_back(j);
}
}
}
return false;
}
int dinic(int startP, int endP)
{
int nMaxFlow = 0;
deque<int> q;
while (countLayer(startP, endP))
{
memset(visited, 0, sizeof(visited));
q.push_back(startP);
visited[startP] = true;
while (!q.empty())
{
int nd = q.back();
if (nd == endP)
{
int nMinC = INF;
int nMinC_vs;
for (int i = 1; i < q.size(); i++)
{
int vs = q[i - 1];
int ve = q[i];
if (nMinC > g[vs][ve])
{
nMinC = g[vs][ve];
nMinC_vs = vs;
}
}
nMaxFlow += nMinC;
for (int i = 1; i < q.size(); i++)
{
int vs = q[i - 1];
int ve = q[i];
g[vs][ve] -= nMinC;
g[ve][vs] += nMinC;
flow[vs][ve] += nMinC;
flow[ve][vs] -= nMinC;
}
while (!q.empty() && q.back() != nMinC_vs)
{
visited[q.back()] = 0;
q.pop_back();
}
}
else
{
int i;
for (i = 0; i <= endP; i++)
{
if (g[nd][i] > 0 && Layer[i] == Layer[nd] + 1 && visited[i] == false)
{
visited[i] = 1;
q.push_back(i);
break;
}
}
if (i > endP)
{
q.pop_back();
}
}
}
}
return nMaxFlow;
}
void solve() //num为节点个数,n*m方阵
{
int i, j, res, sum = 0;
for (i = 0; i <= m + n + 1; i++)
for (j = 0; j <= m + n + 1; j++)
{
g[i][j] = high[i][j] - low[i][j]; //该边容量为上下界流量之差
g[i][tt] += low[i][j];
g[ss][j] += low[i][j];
sum += low[i][j]; //所有边的流量下界之和
}
g[t][s] = INF; //在附加网络中连边cap[t][s]=INF
res = dinic(ss, tt); //对附加网络求解最大流
if (res != sum) //附加网络的最大流不等于所有下界之和,则无解
{
printf("IMPOSSIBLE\n");
return;
}
g[t][s] = g[s][t] = 0; //去掉边(t,s)和(s,t)
res = dinic(s, t); //在对去边及超级汇源之后的图求解最大流
for (i = 1; i <= m; i++) //输出方阵
{
printf("%d", flow[i][1 + m] + low[i][1 + m]);
for (j = 2; j <= n; j++)
printf(" %d", flow[i][j + m] + low[i][j + m]);
printf("\n");
}
}
int main()
{
int i, j, u, v, w, nLimit, ncase;
char ch;
scanf("%d", &ncase);
while (ncase--)
{
scanf("%d%d", &m, &n);
s = 0;
t = m + n + 1;
ss = m + n + 2;
tt = m + n + 3;
memset(low, 0, sizeof(low));
memset(g, 0, sizeof(g));
memset(high, 0, sizeof(high));
memset(flow, 0, sizeof(flow));
for (i = 1; i <= m; i++)
scanf("%d", &rSum[i]);
for (i = 1; i <= n; i++)
scanf("%d", &cSum[i]);
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
high[i][j + m] = INF;
scanf("%d", &nLimit);
while (nLimit--)
{
scanf("%d %d %c %d", &u, &v, &ch, &w);
if (u == 0 && v != 0) //建图
{
if (ch == '=')
{
for (i = 1; i <= m; i++)
low[i][v + m] = high[i][v + m] = w;
}
else if (ch == '<')
{
for (i = 1; i <= m; i++)
high[i][v + m] = min(high[i][v + m], w - 1);
}
else if (ch == '>')
{
for (i = 1; i <= m; i++)
low[i][v + m] = max(low[i][v + m], w + 1);
}
}
else if (u != 0 && v == 0)
{
if (ch == '=')
{
for (i = 1; i <= n; i++)
low[u][i + m] = high[u][i + m] = w;
}
else if (ch == '<')
{
for (i = 1; i <= n; i++)
high[u][i + m] = min(high[u][i + m], w - 1);
}
else if (ch == '>')
{
for (i = 1; i <= n; i++)
low[u][i + m] = max(low[u][i + m], w + 1);
}
}
else if (u == 0 && v == 0)
{
for (i = 1; i <= m; i++)
for (j = 1; j <= n; j++)
{
if (ch == '=')
low[i][j + m] = high[i][j + m] = w;
else if (ch == '<')
high[i][j + m] = min(high[i][j + m], w - 1);
else if (ch == '>')
low[i][j + m] = max(low[i][j + m], w + 1);
}
}
else if (u != 0 && v != 0)
{
if (ch == '=')
low[u][v + m] = high[u][v + m] = w;
else if (ch == '<')
high[u][v + m] = min(high[u][v + m], w - 1);
else if (ch == '>')
low[u][v + m] = max(low[u][v + m], w + 1);
}
}
for (i = 1; i <= m; i++)
low[s][i] = high[s][i] = rSum[i];
for (i = 1; i <= n; i++)
low[i + m][t] = high[i + m][t] = cSum[i];
solve();
printf("\n");
}
return 0;
}
POJ 2135 公园来回 最小费最大流
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN = 10017;
const int MAXM = 100017;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to, cap, cost, flow, next;
//next为上一个节点的下标
Edge(){ }
Edge(int _to,int _cap,int _cost,int _flow,int _next):to(_to),cap(_cap),cost(_cost),flow(_flow),next(_next){ }
};
Edge edge[MAXM];
int head[MAXN];//最后一个节点的下标
int tol;
int pre[MAXN];//点到边
int dis[MAXN];
bool isInQue[MAXN];
int n;
void init()
{
tol = 0;
memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int cap, int cost)//左端点,右端点,容量,花费
{
edge[tol] = Edge(v, cap, cost, 0, head[u]);
head[u] = tol++;
edge[tol] = Edge(u, 0, -cost, 0, head[v]);
head[v] = tol++;
}
bool spfa(int s, int t)
{
queue<int>q;
for (int i = 0; i <=t; i++)
{
dis[i] = INF;
isInQue[i] = false;
pre[i] = -1;
}
dis[s] = 0;
isInQue[s] = true;
q.push(s);
while (!q.empty())
{
int u = q.front();
q.pop();
isInQue[u] = false;
for (int i = head[u]; i != -1; i = edge[i].next)
{
int v = edge[i].to;
if (edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost)
{
dis[v] = dis[u] + edge[i].cost;
pre[v] = i;
if (!isInQue[v])
{
isInQue[v] = true;
q.push(v);
}
}
}
}
if (pre[t] == -1)
return false;
else
return true;
}
//返回的是最大流, cost存的是最小费用
int minCostMaxflow(int s, int t, int &cost)
{
int flow = 0;
cost = 0;
while (spfa(s, t))
{
int Min = INF;
for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to])
{
if (Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
}
for (int i = pre[t]; i != -1; i = pre[edge[i ^ 1].to])
{
edge[i].flow += Min;
edge[i ^ 1].flow -= Min;
cost += edge[i].cost * Min;
}
flow += Min;
}
return flow;
}
int main()
{
int m;
while (~scanf("%d%d", &n, &m))
{
init();//注意
int a, b, c;
for (int i = 1; i <= m; i++)
{
scanf("%d%d%d", &a, &b, &c);
addedge(a, b, 1, c);//无向图
addedge(b, a, 1, c);
}
int beg = 0;//超级起点
int end = n + 1;//超级汇点
addedge(beg, 1, 2, 0);//超级起点,容量为2,花费为
addedge(n, end, 2, 0);//超级汇点容量为2,花费为0
//容量为2,即表示求了2条从起点到汇点的最短路
int ans = 0;
minCostMaxflow(beg, end, ans);
printf("%d\n", ans);
}
return 0;
}