生活随笔
收集整理的這篇文章主要介紹了
BZOJ 1070 修车
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
Description
同一時(shí)刻有\(N\)位車主帶著他們的愛(ài)車來(lái)到了汽車維修中心。維修中心共有\(M\)位技術(shù)人員,不同的技術(shù)人員對(duì)不同的車進(jìn)行維修所用的時(shí)間是不同的。現(xiàn)在需要安排這\(M\)位技術(shù)人員所維修的車及順序,使得顧客平均等待的時(shí)間最小。 說(shuō)明:顧客的等待時(shí)間是指從他把車送至維修中心到維修完畢所用的時(shí)間。
第一行有兩個(gè)\(m,n\),表示技術(shù)人員數(shù)與顧客數(shù)。 接下來(lái)\(n\)行,每行\(m\)個(gè)整數(shù)。第\(i+1\)行第\(j\)個(gè)數(shù)表示第\(j\)位技術(shù)人員維修第\(i\)輛車需要用的時(shí)間\(T_{j,i}\)。
Output
最小平均等待時(shí)間,答案精確到小數(shù)點(diǎn)后\(2\)位。
2 2
3 2
1 4
Sample Output
1.50
HINT
\((2 \le M \le 9,1 \le N \le 60), (1 \le T \le 1000)\)
這是一道比較明顯的費(fèi)用流題目。
這題構(gòu)圖很巧妙:
將每個(gè)工人拆成\(n\)個(gè)點(diǎn),設(shè)第\(i\)個(gè)工人拆成的第\(j\)個(gè)點(diǎn)為\(P_{i,j}\),\(P_{i,j}\)表示第\(i\)個(gè)人倒數(shù)第\(j\)個(gè)修的車是哪一輛。
\(P_{i,j}\)向第\(k\)輛車連接一條容量為\(1\),費(fèi)用為\(T_{i,k} \times j\)的邊。
接著就是連接源匯點(diǎn),最后跑最大費(fèi)用最大流即可。
正確性也很明顯。每個(gè)工人修的車只可以對(duì)它后面修的產(chǎn)生代價(jià),而代價(jià)正好就是它的倒數(shù)名次與其時(shí)間的乘積。
zkw費(fèi)用流是蒯的hzwer的,應(yīng)該可以敲spfa吧。
#include<cstdio>
#include<cstdlib>
#include<queue>
#include<cstring>
using namespace std;
#define inf 0x7fffffff
#define T 601
using namespace std;
int n,m,cnt = 1,ans,t[61][10];
int d[605],q[605],from[605],head[605];
bool mark[605];
struct edge{int from,to,next,c,v;}e[100001];inline int small(int a,int b) {if (a < b) return a; return b;}void ins(int u,int v,int w,int c)
{cnt++;e[cnt].from = u; e[cnt].to = v;e[cnt].next = head[u]; head[u] = cnt;e[cnt].c = c; e[cnt].v = w;
}void insert(int u,int v,int w,int c)
{ins(u,v,w,c); ins(v,u,0,-c);
}bool spfa()
{memset(mark,0,sizeof(mark));memset(d,0x7,sizeof(d));d[T] = 0; mark[T] = 1;queue <int> team;team.push(T);while (!team.empty()){int now = team.front();team.pop();for (int i = head[now];i;i = e[i].next)if (e[i^1].v&&d[e[i].to] > d[now]-e[i].c){d[e[i].to] = d[now]-e[i].c;if (!mark[e[i].to]){mark[e[i].to] = true;team.push(e[i].to);}}mark[now] = false;}if (d[0] > 10000000) return false; return true;
}int dfs(int x,int f)
{if (x == T){mark[T] = 1;return f;}int used = 0,w;mark[x] = true;for (int i = head[x];i;i = e[i].next)if (!mark[e[i].to]&&e[i].v&&d[x]-e[i].c==d[e[i].to]){w = f - used;w = dfs(e[i].to,small(e[i].v,w));ans += w*e[i].c;e[i].v -= w;e[i^1].v += w;used += w;if (used == f) return f;}return used;
}void zkw()
{while (spfa()){mark[T] = 1;while (mark[T]){memset(mark,0,sizeof(mark));dfs(0,inf);}}
}int main()
{freopen("1070.in","r",stdin);freopen("1070.out","w",stdout);int i,j,k;scanf("%d %d",&n,&m);for (i = 1;i<=m;i++)for (j = 1;j<=n;j++)scanf("%d",t[i]+j);for (i = 1;i<=n*m;i++)insert(0,i,1,0);for (int i = n*m+1;i<=n*m+m;i++)insert(i,T,1,0);for (i = 1;i<=n;i++)for (j = 1;j<=m;j++)for (k = 1;k<=m;k++)insert((i-1)*m+j,n*m+k,1,t[k][i]*j);zkw();printf("%.2lf",(double)ans/m);return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/mmlz/p/4314981.html
總結(jié)
以上是生活随笔為你收集整理的BZOJ 1070 修车的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。