1. 程式人生 > >HDU-4292-Food(最大流,拆點,Dinic+向前星)(注意!!此題我認為超坑啊!!!)

HDU-4292-Food(最大流,拆點,Dinic+向前星)(注意!!此題我認為超坑啊!!!)

 

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<stdio.h>
#include<string.h>  
#include<math.h>  
  
#include<map>   
//#include<set>
#include<deque>  
#include<queue>  
#include<stack>  
#include<bitset> 
#include<string>  
#include<fstream>
#include<iostream>  
#include<algorithm>  
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<int> 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<<i<<" :  ";
//			for(int j=head[i];j+1;j=edge[j].nxt)
//				cout<<edge[j].v<<"  - > ";
//			cout<<endl;
//		}
		dinic();
	}
}