【POJ3686】The Windy's

题目

解析:

这道题建模挺妙的,难点在于如何处理累积时间。
首先对于一个车间,如果加工了\(k\)个玩具,那么总时间为

\[(t_1)+(t_1+t_2)+(t_1+t_2+t_3)+...+(t_1+t_2+...+t_k)=kt_1+(k-1)t_2+...+t_k \]

由此我们发现,每一个玩具可以提出来单独算。将每个车间拆成\(n\)个点,第\(i\)个点表示倒数第\(i\)个生产出来的玩具。每个玩具\(j\)分别向\(i\)连一条容量为\(1\),费用为\(i*time[i][j]\)的边。建完图后跑费用流即可。

code:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
using namespace std;

const int Maxn=2555;
const int Maxm=127555;
const int inf=1e9;
int T,n,m,size,s,t,sum;
int first[Maxn],dis[Maxn],tmp[Maxn],vis[Maxn],f[55][55];
struct shu{int to,next,l,c;}e[Maxm<<1];

inline void add(int x,int y,int l,int c)
{
	e[++size].next=first[x],first[x]=size,e[size].to=y,e[size].l=l,e[size].c=c;
}

inline int min(int x,int y){return x>y ? y : x;}

inline void init()
{
	scanf("%d%d",&n,&m);
	t=n*m+n+1,size=-1,sum=0;
	for(int i=s;i<=t;i++) first[i]=-1;
	for(int i=1;i<=n;i++)
	{
	  add(s,i,1,0),add(i,s,0,0);
	  for(int j=1;j<=m;j++)
	  {
	    scanf("%d",&f[i][j]);
	    add(j*n+i,t,1,0),add(t,j*n+i,0,0);
	  }
	}
	for(int i=1;i<=n;i++)
 	  for(int k=1;k<=m;k++)
	    for(int j=1;j<=n;j++)
	      add(i,k*n+j,1,j*f[i][k]),add(k*n+j,i,0,-j*f[i][k]);
}

inline bool spfa()
{
	queue<int>q;
	for(int i=s;i<=t;i++) dis[i]=inf,tmp[i]=first[i];
	q.push(s),dis[s]=0,vis[s]=1;
	while(!q.empty())
	{
	  int p=q.front();q.pop(),vis[p]=0;
	  for(register int u=first[p];~u;u=e[u].next)
	  {
	  	int to=e[u].to;
	  	if(!e[u].l || dis[to]<=dis[p]+e[u].c) continue;
	  	dis[to]=dis[p]+e[u].c;
	  	if(!vis[to]) vis[to]=1,q.push(to);
	  }
	}
	return dis[t]!=inf;
}

inline int dfs(int p,int flow)
{
	if(p==t) return flow;
	int s=0;vis[p]=1;
	for(register int &u=tmp[p];~u;u=e[u].next)
	{
	  int to=e[u].to;
	  if(!e[u].l || dis[to]!=dis[p]+e[u].c || vis[to]) continue;
	  int minn=dfs(to,min(flow-s,e[u].l));
	  e[u].l-=minn,e[u^1].l+=minn,s+=minn,sum+=minn*e[u].c;
	  if(s==flow) break;
	}
	vis[p]=0;
	return s;
}

inline void solve()
{
	while(spfa()){while(dfs(s,inf));}
	printf("%.6f\n",(double)sum/n);
}

int main()
{
	scanf("%d",&T);
	while(T--)
	{
	  init();
	  solve();
	}
	return 0;
}

【POJ3686】The Windy's

上一篇:WPF应用程序界面有哪些样式可以构建?一篇图集带你了解


下一篇:Windows可视化远程Centos