您的位置:首页 > 其它

poj 3686 The Windy's

2014-08-15 17:09 375 查看
很好的一道最小费用流,因为每个工厂一次只能做一个玩具并且可以做多个玩具所以直接用模板不行,那么可以将不同时间同一个工厂所做一个玩具所需要的时间拆分开来为N个只能做一个玩具的工厂所需时间,那么在分别连接起来,建图,最后跑一边最小费用流到得到的就是答案

#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
#define inf 0x7ffffff
#define lc l,m,index<<1
#define rc m+1,r,index<<1|1
#define max_n 10005
#define mod 1000000007
#define FOR(i,s,t) for(int i=(s);i<=(t);++i)
int N,M;
struct edge
{
int to,cap,cost,rev;
};
int V;//顶点数
vector<edge>G[max_n];
int dist[max_n];//最短路
int prevv[max_n],preve[max_n];//前缀点,前缀边
int z[max_n][max_n];
void add_edge(int from,int to,int cap,int cost)
{
G[from].push_back( (edge){to,cap,cost,G[to].size()});
G[to].push_back( (edge) {from,0,-cost,G[from].size()-1});
}
int min_cost_flow(int s,int t,int f)
{
int res=0;
while(f>0)
{
fill(dist,dist+V,inf);
dist[s]=0;
bool update=1;
while(update)
{
update=0;
for(int v=0;v<V;v++)
{
if(dist[v]==inf) continue;
for(int i=0;i<G[v].size();i++)
{
edge &e=G[v][i];
if(e.cap>0 && dist[e.to]>dist[v]+e.cost)
{
dist[e.to]=dist[v]+e.cost;
prevv[e.to]=v;
preve[e.to]=i;
update=1;
}
}
}
}
if(dist[t]==inf) return -1;
int d=f;
for(int v=t;v!=s;v=prevv[v])
{
d=min(d,G[prevv[v]][preve[v]].cap);
// printf("%d %d\n",prevv[v],G[prevv[v]][preve[v]].cap);
// system("pause");
}
f-=d;
res+=d*dist[t];
for(int v=t;v!=s;v=prevv[v])
{
edge &e=G[prevv[v]][preve[v]];
e.cap-=d;
G[v][e.rev].cap+=d;
}
}
return res;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&M);
V=N+M*N+2;
for(int i=0;i<=V;i++)
G[i].clear();
int s=N+M*N,t=s+1;
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
scanf("%d",&z[i][j]);
}
for(int i=0;i<N;i++)
add_edge(s,i,1,0);
for(int j=0;j<M;j++)
{
for(int k=0;k<N;k++)
{
add_edge((j+1)*N+k,t,1,0);
for(int i=0;i<N;i++)
add_edge(i,(j+1)*N+k,1,(k+1)*z[i][j]);
}
}
printf("%.6f\n",(double)min_cost_flow(s,t,N)/(double)N);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: