11. 运输问题1

时间:2021-08-16 21:26:29

★★☆   输入文件:maxflowa.in   输出文件:maxflowa.out   简单对比

时间限制:1 s   内存限制:128 MB

【问题描述】     一个工厂每天生产若干商品,需运输到销售部门进行销售。从产地到销地要经过某些城镇,有不同的路线可以行走,每条两城镇间的公路都有一定的流量限制。请你计算,在不考虑其它车辆使用公路的前提下,如何充分利用所有的公路,使产地运输到销地的商品最多,最多能运输多少商品。 【输入格式】 输入文件有若干行
第一行,一个整数n,表示共有n个城市(2<=n<=100),产地是1号城市,销地是n号城市。
下面有n行,每行有n个数字。第p行第q列的数字表示城镇p与城镇q之间有无公路连接。数字为0表示无,大于0表示有公路,且该数字表示该公路流量。
【输出格式】 输出文件有一行
第一行,1个整数max,表示最大流量为max。
【输入输出样例】 输入文件名: maxflowa.in 6
0 4 8 0 0 0
0 0 4 4 1 0
0 0 0 2 2 0
0 0 0 0 0 7
0 0 0 6 0 9
0 0 0 0 0 0
输出文件名:maxflowa.out 8
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>

using namespace std;
const int N = 1e4 + 10;
const int Maxn = 99999999;

int dis[N], head[N];
bool vis[N];
int n, S, T, now;
struct Node{
int u, v, flow, cap, nxt;
}E[N << 1];
queue <int> Q;

inline int read()
{
int x = 0, f = 1;
char c = getchar();
while(c < '0' || c > '9')
{
if(c == '-')
f = -1;
c = getchar();
}
while(c >= '0' && c <= '9')
{
x = x * 10 + c - '0';
c = getchar();
}
return x * f;
}

inline void add(int u,int v,int cap)
{
E[now].v = v;
E[now].cap = cap;
E[now].flow = 0;
E[now].nxt = head[u];
head[u] = now ++;
}

inline bool bfs()
{
for(int i = 1; i <= n; i ++)
dis[i] = -1;
dis[S] = 0;
Q.push(S);
while(!Q.empty())
{
int topp = Q.front();
vis[topp] = 0;
Q.pop();
for(int i = head[topp]; ~ i; i = E[i].nxt)
{
if(dis[E[i].v] == -1 && E[i].cap - E[i].flow > 0)
{
dis[E[i].v] = dis[topp] + 1;
if(!vis[E[i].v])
{
vis[E[i].v] = 1;
Q.push(E[i].v);
}
}
}
}
return dis[T] == -1 ? 0 : 1;
}

int dfs(int start, int minn)
{
if(start == T || minn < 0)
return minn;
int ret = 0, flo;
for(int i = head[start]; ~ i; i = E[i].nxt)
{
if(dis[E[i].v] == dis[start] + 1 && E[i].cap - E[i].flow > 0)
{
flo = dfs(E[i].v, min(minn, E[i].cap - E[i].flow));
E[i].flow += flo;
E[i ^ 1].flow -= flo;
ret += flo;
minn -= flo;
}
}
return ret;
}

inline void Dinic()
{
int answer = 0;
while(bfs())
answer += dfs(S, Maxn);
printf("%d",answer);
}

int main()
{
freopen("maxflowa.in","r",stdin);
freopen("maxflowa.out","w",stdout);
n = read();
S = 1;
T = n;
for(int i = 1; i <= n ;i ++)
head[i] = -1;
for (int i = 1; i <= n; i ++)
for (int j = 1; j <= n; j ++)
{
int my = read();
if(my)
{
add(i, j, my);
add(j, i, 0);
}
}
Dinic();

return 0;
}