codevs1028 花店橱窗布置


题目描述 Description

假设以最美观的方式布置花店的橱窗,有F束花,V个花瓶,我们用美学值(一个整数)表示每束花放入每个花瓶所产生的美学效果。为了取得最佳的美学效果,必须使花的摆放取得最大的美学值。

输入描述 Input Description

第一行为两个整数F,V(F<=V<=100)

接下来F行每行V个整数,第i行第j个数表示第i束花放入第j个花瓶的美学值。

输出描述 Output Description

一个整数,即最大美学值。

样例输入 Sample Input

2 2

10 0

5 2

样例输出 Sample Output

12
 一道挺裸的题目吧
 跑了费用流,然后单路增广
 em.......
 数据中有负权边
 所以注意spfa前dis数组初始化为-inf(为了这个调了很久TAT)
 然后建边之后一定要调试!一定要调试!一定要调试!(重要的事说三遍) 
 看你建的边对不对
 要不等你整个码完了很难发现是哪里错了
 还有const 的int 要注意区分,不小心弄错了又调了很久
 最后,反向弧要开两倍!!!
#include<cstdio>
#include<cstring>
const int M=103*103*2,N=210,len=10000;
struct node
{
	int from,to,next,v,c;
}e[M];
int first[N];
int s=0,t;
int dis[N],bo[N],qu[len];
int from[N];
int ans=0;
bool spfa()
{
	for(int i=1;i<=t;i++)	dis[i]=1e8*-1;
	dis[0]=0;
	bo[0]=1;
	qu[1]=0;
	int i=1,j=2;
	while(i!=j)
	{
		int r=qu[i++];if(i==len)	i=1;bo[r]=0;
		for(int k=first[r];k;k=e[k].next)
		{
			if(e[k].v>0&&dis[e[k].to]<dis[r]+e[k].c)
			{
				dis[e[k].to]=dis[r]+e[k].c;
				from[e[k].to]=k;
				if(!bo[e[k].to])
				{
					if(dis[e[k].to]>dis[qu[i]])
					{
						i--;if(i<1)	i=len-1;
						qu[i]=e[k].to;
					}
					else 
					{
						qu[j++]=e[k].to;if(j==len)		j=1;
					}
					bo[e[k].to]=1;
				}	
			}
		}
	}
	if(dis[t]<0)	return 0;
	return 1;
}
void fa()
{
	int min=1e8;
	for(int k=from[t];k;k=from[e[k].from])
		min=min<e[k].v?min:e[k].v;
	for(int k=from[t];k;k=from[e[k].from])
		{
			e[k].v-=min;e[k^1].v+=min;
			ans+=e[k].c*min;
		}
}
int main()
{
	int f,n,cnt=1;
	scanf("%d %d",&f,&n);
	t=f+n+1;
	int k;
	for(int i=1;i<=f;i++)
	{//没有写成函数,略丑TAT
		e[++cnt].to=i;e[cnt].from=s;e[cnt].v=1;e[cnt].c=0;e[cnt].next=first[s];first[s]=cnt;
		e[++cnt].to=s;e[cnt].from=i;e[cnt].v=0;e[cnt].c=0;e[cnt].next=first[i];first[i]=cnt;
		for(int j=1;j<=n;j++)
		{
			scanf("%d",&k);
			e[++cnt].to=f+j;e[cnt].v=1;e[cnt].from=i;e[cnt].c=k;e[cnt].next=first[i];first[i]=cnt;
			e[++cnt].to=i;e[cnt].v=0;e[cnt].from=f+j;e[cnt].c=-k;e[cnt].next=first[f+j];first[f+j]=cnt;
			if(i==1)
			{
				e[++cnt].to=t;e[cnt].from=f+j;e[cnt].v=1;e[cnt].c=0;e[cnt].next=first[f+j];first[f+j]=cnt;
				e[++cnt].to=f+j;e[cnt].from=t;e[cnt].v=0;e[cnt].c=0;e[cnt].next=first[t];first[t]=cnt;
			}
		}	
	}
	while(spfa())	fa();
	printf("%d",ans);
	return 0;
}



原文地址:https://www.cnblogs.com/Brian551/p/7353042.html