HDU-4292-Food(最大流,拆点,Dinic+向前星)(注意!!此题我认为超坑啊!!!)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4292

 

Problem Description

  You, a part-time dining service worker in your college’s dining hall, are now confused with a new problem: serve as many people as possible.
  The issue comes up as people in your college are more and more difficult to serve with meal: They eat only some certain kinds of food and drink, and with requirement unsatisfied, go away directly.
  You have prepared F (1 <= F <= 200) kinds of food and D (1 <= D <= 200) kinds of drink. Each kind of food or drink has certain amount, that is, how many people could this food or drink serve. Besides, You know there’re N (1 <= N <= 200) people and you too can tell people’s personal preference for food and drink.
  Back to your goal: to serve as many people as possible. So you must decide a plan where some people are served while requirements of the rest of them are unmet. You should notice that, when one’s requirement is unmet, he/she would just go away, refusing any service.

 

 

Input

  There are several test cases.
  For each test case, the first line contains three numbers: N,F,D, denoting the number of people, food, and drink.
  The second line contains F integers, the ith number of which denotes amount of representative food.
  The third line contains D integers, the ith number of which denotes amount of representative drink.
  Following is N line, each consisting of a string of length F. e jth character in the ith one of these lines denotes whether people i would accept food j. “Y” for yes and “N” for no.
  Following is N line, each consisting of a string of length D. e jth character in the ith one of these lines denotes whether people i would accept drink j. “Y” for yes and “N” for no.
  Please process until EOF (End Of File).

 

 

Output

  For each test case, please print a single line with one integer, the maximum number of people to be satisfied.

 

Sample Input
4 3 3
1 1 1
1 1 1
YYN
NYY
YNY
YNY
YNY
YYN
YYN
NNY
 


Sample Output
3

题目大意:类似之前的牛吃饭喝水的问题,POJ-3281

只不过把下面的数字用字母代替了;

数组应该会超时把,用的向前星,比较水的一道题,拆点+Dinic板子。

这样做没问题,开的数组是2000的,感觉够用,但是!!!

一开始我用的G++交,一直 T 。然后我换成C++,RE,一脸懵逼??

没办法,数组加0

10000   RE        20000  RE            100000  RE                200000  RE        1000005 AC

WTF??看了一下时间,800ms+。。。。,然后又用G++交了一下  500ms+。。。

???啥玩意??搞不懂G++和C++到底用那个了??

这个是G++的:

算了,不吐槽了。。这个水题让我改了TMD一上午!!心态有点小爆炸。。

 

哦!!注意:还有一点就是输入要多组重复输入,输人吃饭喝水的时候是先是光吃饭n行,然后是光喝水n行。。我之前一直觉得是一个人吃饭。。喝水,接着是另一个人。。关键这还能过样例!!。。。。

ac:

#include
#include  
#include  
  
#include   
//#include
#include  
#include  
#include  
#include 
#include  
#include
#include  
#include  
using namespace std;  

#define ll long long  
#define INF 0x3f3f3f3f  
#define mod 998244353
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b) 
#define clean(a,b) memset(a,b,sizeof(a))// 水印 
//std::ios::sync_with_stdio(false);

struct node{
	int v,w,nxt;
	node(int _v=0,int _w=0,int _nxt=0):
	v(_v),w(_w),nxt(_nxt){}
}edge[1000005];
int head[1000005],e;
int dis[1000005];
int n,f,d;
int s,t;

void add(int u,int v,int w)
{
	edge[e]=node(v,w,head[u]);
	head[u]=e++;
	edge[e]=node(u,0,head[v]);
	head[v]=e++;
}

bool bfs()
{
	clean(dis,-1);
	dis[s]=0;
	queue que;
	que.push(s);
	while(que.size())
	{
		int u=que.front();
		que.pop();
		if(u==t)
			return 1;
		for(int i=head[u];i+1;i=edge[i].nxt)
		{
			int temp=edge[i].v;
			if(dis[temp]<0&&edge[i].w>0)
			{
				dis[temp]=dis[u]+1;
				que.push(temp);
			}
		}
	}
	return 0;
}

int dfs(int u,int low)
{
	if(u==t)
		return low;
	int res=0;
	for(int i=head[u];i+1;i=edge[i].nxt)
	{
		int temp=edge[i].v;
		if(dis[temp]==dis[u]+1&&edge[i].w>0)
		{
			int d=dfs(temp,min(low-res,edge[i].w));
			edge[i].w-=d;
			edge[i^1].w+=d;
			res+=d;
			if(res==low)
				return res;
		}
	}
	return res;
}

void dinic()
{
	int ans=0,res;
	while(bfs())
	{
		while(res=dfs(s,INF))
			ans+=res;
	}
	printf("%d\n",ans);
}

void intt()
{
	e=0;
	clean(head,-1);
}

int main()
{
	while(scanf("%d%d%d",&n,&f,&d)!=EOF)
	{
		intt();
		s=0,t=4*200+1;
		int num;
		for(int i=1;i<=f;++i)
		{
			scanf("%d",&num);
			add(s,i,num);
		}
		for(int i=1;i<=d;++i)
		{
			scanf("%d",&num);
			add(i+3*200,t,num);
		}
		char str[210];
		for(int i=1;i<=n;++i)
		{
			clean(str,'\0');
			scanf("%s",str);
			int l=strlen(str);
			for(int j=1;j<=l;++j)
			{
				if(str[j-1]=='Y')
					add(j,i+200,1);
			}
		}
		for(int i=1;i<=n;++i)
		{
			clean(str,'\0');
			scanf("%s",str);
			int l=strlen(str);
			for(int j=1;j<=l;++j)
			{
				if(str[j-1]=='Y')
					add(i+200*2,j+3*200,1);
			}
		}
		for(int i=1;i<=n;++i)
			add(i+200,i+2*200,1);
//		for(int i=0;i<=801;++i)
//		{
//			cout< ";
//			cout<

 

 

 

你可能感兴趣的:(网络流)