POJ 3686.The Windy's 最小費用最大流
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 5477 | Accepted: 2285 |
Description
The Windy‘s is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receives N orders for toys. The manager knows that every order will take different amount of hours in different workshops. More precisely, the i
The manager wants to minimize the average of the finishing time of the N
Input
The first line of input is the number of test case. The first line of each test case contains two integers, N and M (1 ≤ N,M ≤ 50).
The next N lines each contain M integers, describing the matrix Zij (1 ≤ Zij ≤ 100,000) There is a blank line before each test case.
Output
For each test case output the answer on a single line. The result should be rounded to six decimal places.
Sample Input
3 3 4 100 100 100 1 99 99 99 1 98 98 98 1 3 4 1 100 100 100 99 1 99 99 98 98 1 98 3 4 1 100 100 100 1 99 99 99 98 1 98 98
Sample Output
2.000000 1.000000 1.333333
Source
POJ Founder Monthly Contest – 2008.08.31, windy7926778 題目鏈接:http://poj.org/problem?id=3686 題意:有n個玩具m個工廠,一個工廠同時只能生產一個玩具。問平均每個玩具的生產時間。 思路:現在有n個玩具,m個工廠,但是一個工廠可以生產多個玩具。當一個工廠按順序生產a1,a2,a3...,an玩具,每個玩具的生產時間為Za1,Za1+Za2,Za1+Za2+Za3,...,Za1+Za2+Za3+...+Zan。T=n*Za1+(n-1)*Za2+(n-2)*Za3+...+Zan。這個式子也可以理解為,多個只能生產1個玩具的工廠,但是時間為1~n倍。代碼:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<set> #include<map> #include<queue> #include<stack> #include<vector> using namespace std; typedef long long ll; typedef pair<int,int> P; #define PI acos(-1.0) const int maxn=3e5+100,maxm=1e5+100,inf=0x3f3f3f3f,mod=1e9+7; const ll INF=1e18+7; struct edge { int from,to; int cap,cost; int rev; }; int NN; vector<edge>G[maxn]; int h[maxn]; ///頂點的勢,取h(u)=(s到u的最短距離),邊e=(u,v)的長度變成d`(e)=d(e)+h(u)-h(v)>=0 int dist[maxn]; int prevv[maxn],preve[maxn];///前驅結點和對應的邊 void addedge(int u,int v,int cap,int cost) { edge e; e.from=u,e.to=v,e.cap=cap,e.cost=cost,e.rev=G[v].size(); G[u].push_back(e); e.from=v,e.to=u,e.cap=0,e.cost=-cost,e.rev=G[u].size()-1; G[v].push_back(e); } int min_cost_flow(int s,int t,int f) { int res=0; fill(h,h+NN,0); while(f>0) { priority_queue<P,vector<P>,greater<P> >q; fill(dist+1,dist+NN,inf); dist[s]=0; q.push(P(dist[s],s)); while(!q.empty()) { P p=q.top(); q.pop(); int u=p.second; if(dist[u]<p.first) continue; for(int i=0; i<G[u].size(); i++) { edge e=G[u][i]; if(e.cap>0&&dist[e.to]>dist[u]+e.cost+h[u]-h[e.to]) { dist[e.to]=dist[u]+e.cost+h[u]-h[e.to]; prevv[e.to]=u; preve[e.to]=i; q.push(P(dist[e.to],e.to)); } } } if(dist[t]==inf) return res; for(int i=0; i<NN; i++) h[i]+=dist[i]; int d=f; for(int i=t; i!=s; i=prevv[i]) d=min(d,G[prevv[i]][preve[i]].cap); f-=d; res+=d*h[t]; for(int i=t; i!=s; i=prevv[i]) { //cout<<i<<" "; edge &e=G[prevv[i]][preve[i]]; e.cap-=d; G[i][e.rev].cap+=d; } //cout<<s<<endl; } return res; } int z[100][100]; int main() { int T; scanf("%d",&T); while(T--) { int n,m; scanf("%d%d",&n,&m); int s=0,t=n+n*m+1; NN=t+1; for(int i=1; i<=n; i++) { addedge(s,i,1,0); for(int j=1; j<=m; j++) { scanf("%d",&z[i][j]); for(int k=1; k<=n; k++) addedge(i,n+(j-1)*n+k,1,k*z[i][j]); } } for(int j=1; j<=m; j++) { for(int k=1; k<=n; k++) addedge(n+(j-1)*n+k,t,1,0); } printf("%.6f\n",min_cost_flow(s,t,inf)*1.0/n); for(int i=0; i<NN; i++) G[i].clear(); } return 0; }最小費用最大流
POJ 3686.The Windy's 最小費用最大流