这里的边是单向的。。。因为水流不可逆。 打成双向边wrong了一下。。
给不愿看题目的孩子看题意:
第一行:N,M代表N条边,M个点
下面N行 u,v,cap :u点到v点的流限cap
问从1点(源点)到M点(汇点)的最大流
水流是不会寻找方向的,所以找到的可行流都是水会流过的地方Ps:能流水都流,不能流就已满,BFS判断能否流,并用pre数组记录这条可行流。
给不愿看题目的孩子看题意:
第一行:N,M代表N条边,M个点
下面N行 u,v,cap :u点到v点的流限cap
问从1点(源点)到M点(汇点)的最大流
水流是不会寻找方向的,所以找到的可行流都是水会流过的地方Ps:能流水都流,不能流就已满,BFS判断能否流,并用pre数组记录这条可行流。
裸裸的题,裸裸的码
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
#define N 205
#define M 205
#define INF 1<<30
struct node{
int from,to,flow,cap;//flow代表这条边还可以流过多少水,cap代表流上限
}edge[M*2],E;
vector<int>G[N];
int e;//汇点
int d[N],edgenum;//网络流的层次
int pre[N];//记录一条允许流,pre[i]代表连接i点的边
inline int Min(int a,int b){return a>b?b:a;}
void addedge(int u,int v,int cap){
E.from=u,E.to=v,E.cap=cap,E.flow=cap;
edge[edgenum]=E;
G[u].push_back(edgenum++);
}
bool BFS(){
queue<int>q;while(!q.empty())q.pop();
memset(d,-1,sizeof(d));
q.push(1); d[1]=0;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<G[u].size();i++)
{
int v=edge[G[u][i]].to;
if(d[v]==-1&&edge[G[u][i]].flow>0)
{
d[v]=d[u]+1;
pre[v]=G[u][i];//边的编号
if(v==e)return true;
q.push(v);
}
}
}
return false;
}
int change(){
int liu=INF;//代表这条可行流的最大值
for(int i=e;i!=1;i)
{
int num=pre[i];
liu=Min(liu,edge[num].flow);//这条可行流的上限是每条边剩余的flow的值
i=edge[num].from;
}
for(int i=e;i!=1;){
int num=pre[i];
edge[num].flow-=liu;//减少这条可行流中每条边可以流过的水量
i=edge[num].from;
}
return liu;
}
int solve(){
int res=0;
while(BFS()){
res+=change();
}
return res;
}
int main(){
int bian,i;
while(~scanf("%d%d",&bian,&e)){
for(i=1;i<=e;i++)G[i].clear();
edgenum=0;
for(i=0;i<bian;i++)
{
int u,v,cap,temp;scanf("%d%d%d",&u,&v,&cap);
addedge(u,v,cap);
}
int ans=solve();
printf("%d\n",ans);
}
return 0;
}