测试模板能不能过的——————题目链接
邻接矩阵存图
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
const int inf = 0x3f3f3f3f;
const int maxn = 10050;
using namespace std;
int n, m;
int s, t;
int maps[maxn][maxn], pre[maxn], flow[maxn], maxflow;
//maps 邻接矩阵 pre[i] 记录增广路上的i点的前一个点 flow[i]表示从源点到该点的增广路上的可改进量
int bfs()//用bfs去找增广路
{
queue <int> q;
while(!q.empty())
q.pop();
for(int i=0; i<=n; i++)
pre[i] = -1;
pre[s] = 0;
flow[s] = inf;
q.push(s);
while(!q.empty()){
int x = q.front();
q.pop();
if(x == t)
break;
for(int i=1; i<=n; i++){
if(maps[x][i]>0 && pre[i]==-1){
q.push(i);
pre[i] = x;//记录前置点
flow[i] = min(flow[x], maps[x][i]);//更新可改进量
}
}
}
if(pre[t] == -1)
return -1;
return flow[t];
}
void EK(){
int a = bfs();
while(a!=-1)//是否有增广路
{
//printf("%d****
", a);
int k = t;
while(k != s){
int last = pre[k];
//这里是一条 点last ---> 点k 的边
maps[last][k] -= a;//前向弧
maps[k][last] += a;//后向弧
k = last;
}
maxflow += a;
a = bfs();
}
}
int main()
{
scanf("%d%d%d%d", &n, &m, &s, &t);
for(int i=0; i<m; i++){
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
maps[a][b] += w;
}
EK();
printf("%d
", maxflow);
return 0;
}
邻接矩阵存图,只拿到了70分,有三个点MLE了
不过这个还是很好写的
邻接表(链式前向星实现)
#include <bits/stdc++.h>
const int maxn = 10050;
const int inf = 0x3f3f3f3f;
using namespace std;
struct note{
int u, v, w;
int next;
}e[maxn*20]; //边数开大点
int head[maxn], cnt;
int pre[maxn], vis[maxn];
//pre[i] 记录的是增广路上的i点的前一条边在的e数组中的位置
int n, m, s, t;
void add(int u, int v, int w){
e[cnt].u = u, e[cnt].v = v, e[cnt].w = w;
e[cnt].next = head[u], head[u] = cnt++;
//建边建两条,是不是很像残留网络
e[cnt].u = v, e[cnt].v = u, e[cnt].w = 0;
e[cnt].next = head[v], head[v] = cnt++;
}
bool bfs(){//找增广路
queue <int> q;
memset(pre, -1, sizeof(pre));
memset(vis, false, sizeof(vis));
vis[s] = true;
q.push(s);
while(!q.empty()){
int u = q.front();
q.pop();
for(int i=head[u]; ~i; i=e[i].next){
int v = e[i].v;
if(e[i].w>0 && !vis[v]){
pre[v] = i;
vis[v] = true;
if(v == t)//找到
return true;
q.push(v);
}
}
}
return false;
}
void EK()
{
int maxflow = 0;
int a;
while(bfs()){
a = inf;
int i = pre[t];
while(~i){ //找适合的增量
a = min(a, e[i].w);
i = pre[e[i].u];
}
i = pre[t];
while(~i){
e[i].w -= a; //想象下残留网络
e[i^1].w += a;
i = pre[e[i].u];
}
maxflow += a;
}
printf("%d
", maxflow);
}
int main()
{
memset(head, -1, sizeof(head));
cnt = 0;
scanf("%d%d%d%d", &n, &m, &s, &t);
for(int i=0; i<m; i++){
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
add(a, b, w);
}
EK();
return 0;
}