首页 > 其他分享 >poj 3281(最大流)

poj 3281(最大流)

时间:2023-05-29 22:32:17浏览次数:37  
标签:pre map include 最大 flow poj now 3281 define


解题思路:

这是道匹配的问题,最近刚学网络流,所以想用网络流去做。。按照题目要求,我开始建立的是food----cow----drink的图,源点与所有的food的编号连接,所有的drink的编号与汇点连接,这里所有的有向边的容量都为1,。。但很不幸的是WA了。。看了别人的思路,我才知道原来这里保证不了一头牛只能吃一份食物和饮料。。把牛分成两份,相同的牛之间建立一条容量为1的边,这样就保证一头牛只能有1的流量经过,这样就能够使得每头牛吃一份啦。。。这道题目确实很巧妙,是道好题。。

AC:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define inf 1000
#define nMax 410
#define Max(a,b) (a>b?a:b)
#define Min(a,b) (a<b?a:b)

int map[nMax][nMax];
int N,F,D;
int path[nMax];
int queue[nMax * 100];
int head,end;
//bool flag[nMax];
//广搜求一条增广路
int bfs()
{
	int minFlow = inf,u;
	memset(path, -1, sizeof(path));
	head = 0;
	end = 1;
	queue[head] = 0;
	while (head < end)
	{
		u = queue[head ++];
		if (u == 2 * N + F + D + 1)
		{
			break;
		}
		for (int i = 1; i <= 2 * N + F + D + 1; ++ i)
		{
			if (path[i] == -1 && map[u][i] )
			{
				if (minFlow > map[u][i])
				{
					minFlow = map[u][i];
				}
				queue[end ++] = i;
				path[i] = u;
				
			}
		}
	}
	if (path[2 * N + F + D + 1] == -1)
	{
		return -1;
	}
	return minFlow;
}
//EK算法,每次广搜得到一条增广路径,然后更新残留网络
void Edmods_Karp()
{
	int flow, maxFlow = 0, now, pre;
	while ((flow = bfs()) != -1)
	{
		maxFlow += flow;
		now = 2 * N + F + D + 1;
		while (now != 0)
		{
			pre = path[now];
			map[pre][now] -= flow;
			map[now][pre] += flow;
			now = pre;
		}
	}
	printf("%d\n", maxFlow);
}
//按照源点-食物-牛-牛-饮料-汇点的顺序建图
void buildMap()
{
	int fNum,dNum,fd;
	while (scanf("%d %d %d", &N, &F, &D) != EOF)
	{
		memset(map, 0, sizeof(map));
		//memset(flag, false, sizeof(flag));
		for (int i = 1; i <= N; ++ i)
		{
			scanf("%d %d", &fNum, &dNum);
			for (int j = 0; j < fNum; ++ j)
			{
				scanf("%d", &fd);
				map[0][fd] = 1;
				map[fd][i + F] = 1;
			}
			map[i + F][i + F + N] = 1;
			for (int j = 0; j < dNum; ++ j)
			{
				scanf("%d", &fd);
				map[fd + 2 * N + F][F + 2 * N + D + 1] = 1;
				map[i + F + N][fd + 2 * N + F] = 1;
			}
		}
		Edmods_Karp();
	}
}
//注意这里给点编号,0-源点,1-F是食物,F+1-F+N是牛左点,F+N+1-F+N+N是牛右点,F+N+N+1-F+N+N+D是drink饮料点,F+N+N+D+1是汇点

int main()
{
	buildMap();
	return 0;
}




标签:pre,map,include,最大,flow,poj,now,3281,define
From: https://blog.51cto.com/u_16143128/6374348

相关文章

  • hdu 1532(最大流)
    解题思路:这是一道典型的模板题,直接套用EK算法即可。。。我感觉最大流的本质就是能否找到一个从源点到汇点的增广路径,并将其最小的边作为增加值,沿着增广路上的边进行更新。AC:#include<iostream>#include<cstdio>#include<cstring>#include<queue>usingnamespacestd;consti......
  • 后GPT时代,多模态是最大的机会
    作者:王咏刚,SeedV实验室创始人/CEO,创新工场AI工程院执行院长编者按:ChatGPT/GPT-4的横空出世,已经彻底改变了NLP领域的研究态势,并以其多模态的潜能,点燃了人们心中通往AGI的第一簇火花。AI2.0时代因此而至。但新时代的技术列车将通往何方?全新的商业机会又埋藏在何处?SeedV实验室创始......
  • Unity 对多边形进行矩形分割和查找最大内接矩形
     花了点时间实现了对任意多边形进行矩形分割的功能,有需要的小伙伴可以点这里查看源码 一、实现效果:1、对图片里的内容进行矩形分割     2、对多边形顶点数据进行矩形分割    3、查找图片里内容的最大内接矩形    4、查找多边形顶点数据内的最大内......
  • poj 1935(搜索+回溯)
    解题思路:先我们考虑从源点出发到所有自己想要经过的点然后在回到源点sum,显然每条边都必须经过源点(这个我们可以一次dfs求出),但题目的意思是可以不用回到源点,那么我们可以再求源点到所有要经过的点的最远距离ans,于是答案便是sum-ans.这道题的思路确实是很巧妙,一开始我还是在想如......
  • poj 2346(DP)
    题意:n位数,满足前n/2个数字之和同后n/2个数字之和相同的数一共有多少个?解题思路:dp[i][j]表示前i个数的和为j时,有多少个;递推关系:dp[i][j]+=dp[i-1][k],k表示前i-1个数的和,由于每一位只能是0-9,所以有限制条件:9>=j - k>=0由于对称性,只需要枚举到n/2即可,剩下的就是简单的乘法......
  • poj 2415(BFS)
    题意: 有一种游戏,共有三个piece(不妨称为棋子),棋盘是由N个点构成的完全图,边有颜色。每次可以移动一个棋子,移动时必须满足棋子走过的边的颜色和其他两个棋子之间的连边的颜色一致。求把三个棋子移到同一个顶点的最少次数。这道题是一个很简单的BFS,但为何一直TLE。。。。#include<ios......
  • poj 1054
    解题思路:这道题其实比较简单,就是找斜率相同且间距相同的点。首先,就是要找到两点,确定好斜率,然后就判断这两点是否在起始位置。其次,确定好斜率就确定了两个点之间的距离,如果某两点之间的间距不满足的话,那么这个点肯定不是这个方向上的。#include<iostream>#include<cstdio>#include......
  • poj 2010(优先队列)
    题意:奶牛大学:奶大招生,从C头奶牛中招收N头。它们分别得分score_i,需要资助学费aid_i。希望新生所需资助不超过F,同时得分中位数最高。求此中位数。解题思路:这里要求最大中位数,中位数肯定是在这些人中间,故可以枚举中位数,可以先对分数进行排序,然后用二分去找最大中位数。每次枚举的中位......
  • poj 1948(搜索+剪枝)
    解题思路:这道题看到数据量,想到应该搜索+剪枝应该可以过。。可是别人的A了,我的却超时了。。。我用了一个mark[a][b],表示前两条边长度分别为a和b时,是否已经处理过,如果是的话就直接跳出。。。剩下的就是一个比较简单的搜索过程了,代码不难写,但是确实超时不可避免。。#include<iostream>......
  • poj 1604
    题意:计算n!最后一位不为0的数解题思路:1*2*3*......*n,每次乘完一个数后,把末尾0去掉,然后模上一个数,这样算出来的数肯定是最后一位不为0的数。。注意这里模的数不能太小,同时也不能太大,太小可能会影响乘积的效果,譬如可能出现0的情况被之前的模运算给抹掉了,太大就直接溢出了。。。参考了......