现在的位置: 首页 > 综合 > 正文

HDU 1532

2013年10月18日 ⁄ 综合 ⁄ 共 1414字 ⁄ 字号 评论关闭

这里的边是单向的。。。因为水流不可逆。 打成双向边wrong了一下。。
给不愿看题目的孩子看题意:
第一行: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;
} 

抱歉!评论已关闭.