HDU 4292 Food(筑图+最大流)
请不要随便指点别人该怎么做、每个人的人生都应该自己掌握、你给不了别人一切、你也不懂别人的忧伤、
微笑不代表快乐、哭泣不一定悲伤
不努力怎么让关心你的人幸福、不努力怎么让看不起你的人绝望、
我用生命在奋斗——lx_Zz
—————————————————————————————————————————————————————————————
————————————————————————— 华丽的分割线 ————————————————————————————
—————————————————————————————————————————————————————————————
110 | 给我再去相信的勇气、 | 125MS | 2176K | 3106B | C++ | 2014-05-07 16:56:58 |
2道2012年成都网络赛的最大流水题都切了、
感觉建模建的不怎么好、、、、
建立两个超级源点和汇点、将food和drink分别连在其中一个点上、然后建人拆点、因为每个能只能有1的流量、所以拆点限制流量、
然后将food和人、drink和人对应的连起来、就OK了
/* 题目: HDU 4292 Food */ /* 作者: lx_Zz */ /* 时间: 2014.5.7 */ #include<cstdio> #include<queue> #include<vector> #include<map> #include<string> #include<iostream> #include<cmath> #include<cstdlib> #include<cstring> #include<algorithm> using namespace std; #define INF 0x7fffffff #define LL __int64 #define N 1005 int f_num[N]; int d_num[N]; char str[N]; int k; int level[N]; struct node { int to,next,cost; }edge[N*N]; int head[N]; int t_head[N]; int start,end; void init() { k=0; memset(head,-1,sizeof(head)); } int bfs(int s,int t)//对顶点进行标号、找出层次图 { memset(level,0,sizeof(level)); queue<int>q; q.push(s); level[s]=1; while(!q.empty()) { int now=q.front(); q.pop(); for(int i=head[now];i!=-1;i=edge[i].next) { int y=edge[i].to; if(!level[y]&&edge[i].cost>0) { level[y]=level[now]+1; q.push(y); } } } return level[t]!=0;//汇点是否在层次图中 } int dfs(int s,int cp)//在层次图中寻找增广路进行增广 { int flow=0,temp; int t; if(s==end||cp==0)return cp; for(;t_head[s]+1;t_head[s]=edge[t_head[s]].next) { int y=edge[t_head[s]].to; if(level[s]+1==level[y]) { temp=dfs(y,min(cp,edge[t_head[s]].cost)); if(temp>0) { edge[t_head[s]].cost-=temp; edge[t_head[s]^1].cost+=temp; flow+=temp; cp-=temp; if(cp==0)break; } } } return flow; } int dinic() { int ans=0,flow=0; while(bfs(start,end))//汇点不在层次图中、算法终止 { for(int i=0;i<=end;i++) t_head[i]=head[i]; ans+=dfs(start,INF); } return ans; } void add(int x,int y,int val) { edge[k].to=y; edge[k].cost=val; edge[k].next=head[x]; head[x]=k++; edge[k].to=x; edge[k].cost=0; edge[k].next=head[y]; head[y]=k++; } int main() { //freopen("C:\\Users\\终将我要华丽的逆袭\\Desktop\\lx_Zz_in.txt","r",stdin); //freopen("C:\\Users\\终将我要华丽的逆袭\\Desktop\\lx_Zz_out.txt","w",stdout); int n,f,d; while(scanf("%d%d%d",&n,&f,&d)!=EOF) { init(); start=0;end=f+d+n*2+1; for(int i=1;i<=n;i++) { add(i*2-1,i*2,1); } for(int i=1;i<=f;i++) scanf("%d",&f_num[i]); for(int i=1;i<=d;i++) scanf("%d",&d_num[i]); for(int i=1;i<=f;i++) { add(start,n*2+i,f_num[i]); } for(int i=1;i<=d;i++) { add(n*2+f+i,end,d_num[i]); } for(int i=1;i<=n;i++) { scanf("%s",str+1); for(int j=1;j<=f;j++) { if(str[j]=='Y') { add(n*2+j,i*2-1,1); } } } for(int i=1;i<=n;i++) { scanf("%s",str+1); for(int j=1;j<=d;j++) { if(str[j]=='Y') { add(i*2,n*2+f+j,1); } } } printf("%d\n",dinic()); } return 0; }