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;
}
#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;
}
相关文章推荐
- POJ-3686-TheWindy's
- POJ 3686 The Windy's & HDU 3718 Similarity
- poj3686 The Windy's
- poj 3686 The Windy's 二分匹配 KM算法求最小权匹配
- Poj 3686 The Windy's【KM匹配】
- poj 3686 The Windy's
- poj 3686 The Windy's(最小费用最大流)
- poj 3686 The Windy's 二分图最小权和匹配KM
- [ACM] POJ 3686 The Windy's (二分图最小权匹配,KM算法,特殊建图)
- poj 3686 The Windy's
- The Windy's (poj 3686 最小费用最大流 建图经典)
- POJ 3686 The Windy's
- POJ 3686 The Windy's
- The Windy's - POJ 3686 KM算法
- 【POJ 3686 The Windy's】+ 最小费用流
- POJ 3686_The Windy's
- poj 3686 The Windy's (KM算法)
- POJ 3686 The Windy's 指派问题 拆点
- POJ_3686_The Windy's(最小费用流)
- POJ 3686 The Windy's KM算法