最大流网络流(基础EK)

2 篇文章 0 订阅
#include"stdio.h"
#include"string.h"
#include<queue>
using namespace std;
const int INF = 1<<29;


int main()
{
int n,m,s,t;
freopen("data.txt", "r", stdin);
while(scanf("%d%d", &n, &m) == 2)
{
scanf("%d%d", &s, &t);
int i;
int map[10][10];
int flow[10][10];
int a[10];
memset(map, 0, sizeof(map));
memset(flow, 0, sizeof(flow));
int st,ed,cost;
for(i = 0; i < m; i++)
{
scanf("%d%d%d", &st, &ed, &cost);
map[st][ed] = cost;
}
int f = 0;
queue<int>q;
int p[10];
while(1)
{
memset(a, 0, sizeof(a));
a[s] = INF;
q.push(s);
while(!q.empty())
{
int u = q.front();q.pop();
for(int v = 0; v < n; v++)
if(!a[v] && map[u][v] > flow[u][v])
{
p[v] = u;
q.push(v);
a[v] = a[u] < (map[u][v]-flow[u][v]) ? a[u]:(map[u][v]-flow[u][v]);
}
}
if(a[t] == 0) break;
for(int u = t; u !=s; u = p[u])
{
flow[p[u]][u] += a[t];
flow[u][p[u]] -= a[t];
}
f += a[t];
}
printf("%d\n", f);
}
return 0;

}


最小割

#include"stdio.h"
#include"string.h"
#include<queue>
using namespace std;
const int INF = 1<<30;
const int N = 15;
int map[N][N];
int flow[N][N];
int cap[N];
int vis[N];
int p[N];
int f = 0;
int n,m;
void init()
{
memset(vis, 0, sizeof(vis));
memset(flow, 0, sizeof(flow));
memset(map, 0, sizeof(map));
f = 0;
}
int min(int x, int y)
{
return x<y?x:y;
}
void MAX_Flow()
{
int s,t,u,v;
s = 1;
t = n;
queue<int>q;
while(1)
{
memset(cap, 0, sizeof(cap));
cap[s] = INF;
q.push(s);
while(!q.empty())
{
u = q.front();q.pop();
for(v = 1; v <= n; v++)
if(!cap[v] && map[u][v])
{
p[v] = u;
cap[v] = min(cap[u], map[u][v]);
q.push(v);
}
}
if(cap[t] == 0) break;
for(u = t; u != s; u=p[u])
{
//flow[p[u]][u] += cap[t];
//flow[u][p[u]] -= cap[t];
map[p[u]][u] -= cap[t];
map[u][p[u]] += cap[t];

}
f += cap[t];
}
}
void Min_Edge(int st)
{
int i;
vis[st] = 1;
for(i = 1; i <= n; i++)
{
if(vis[i] == 0 && map[st][i] != 0 && i!= st)
{
vis[i] = 1;
Min_Edge(i);
}
}
}


void Print_Edge()
{
int i;
printf("S:\n");
for(i = 1; i <= n; i++)
if(vis[i])
printf("%d ", i);

printf("\n");
printf("T:\n");
for(i = 1; i <= n; i++)
if(!vis[i])
printf("%d ", i);
printf("\n");
}


int main()
{
freopen("data.txt", "r", stdin);
int i,j,u,v,cost;
while(scanf("%d%d", &n, &m) == 2)
{
init();
for(i = 1; i <= m; i++)
{
scanf("%d%d%d", &u, &v,&cost);
map[u][v] = cost;
}
MAX_Flow();
printf("Max Flow:%d\n", f);
Min_Edge(1);
Print_Edge();



}
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值