日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[SCOI2007] 修车(费用流 + 差分时间段建图)

發布時間:2023/12/3 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [SCOI2007] 修车(费用流 + 差分时间段建图) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

problem

luogu-P2053

solution

假設只有一個工作人員。修車順序為 p1,p2,...,pnp_1,p_2,...,p_np1?,p2?,...,pn? 是一個 nnn 的排列。

那么對于第 iii 個被修的車的等待時間應為 Tp1+...TpiT_{p_1}+...T_{p_i}Tp1??+...Tpi??

總的等待時間則是 Tp1+(Tp1+Tp2)+...+(Tp1+...+Tpn)=Tp1?n+Tp2?(n?1)+...+TpnT_{p_1}+(T_{p_1}+T_{p_2})+...+(T_{p_1}+...+T_{p_n})=T_{p_1}*n+T_{p_2}*(n-1)+...+T_{p_n}Tp1??+(Tp1??+Tp2??)+...+(Tp1??+...+Tpn??)=Tp1???n+Tp2???(n?1)+...+Tpn??

observation1:\text{observation1}:observation1: 所有車的等待時間就是所有車主的等待時間。

observation2:\text{observation2}:observation2: 越晚修的車對應的修車時間貢獻越少

從每輛車被等待的時間考慮,每個師傅一次修一輛車,我們按照車輛數將修車師傅拆成 n?mn*mn?m 個點。

車與源點連邊,師傅與匯點連邊,第 iii 輛車和在 kkk 時間段被 jjj 師傅修理連邊,花費 Ti,j?kT_{i,j}*kTi,j??k 表示其修車時間對總時間的貢獻。

跑一個最小費用流即可。

如果有興趣更深入地研究一下此題,可以做 NOI的《美食節》一題

code

#include <bits/stdc++.h> using namespace std; #define maxn 1000 struct node { int to, nxt, flow, cost; }E[maxn * maxn]; int head[maxn], dis[maxn], lst[maxn], vis[maxn]; queue < int > q; int m, n, s, t, cnt = -1;void addedge( int u, int v, int w, int c ) {E[++ cnt] = { v, head[u], w, c }, head[u] = cnt;E[++ cnt] = { u, head[v], 0,-c }, head[v] = cnt; }bool SPFA() {memset( dis, 0x3f, sizeof( dis ) );memset( lst, -1, sizeof( lst ) );dis[s] = 0; q.push( s );while( ! q.empty() ) {int u = q.front(); q.pop(); vis[u] = 0;for( int i = head[u];~ i;i = E[i].nxt ) {int v = E[i].to;if( dis[v] > dis[u] + E[i].cost and E[i].flow ) {dis[v] = dis[u] + E[i].cost; lst[v] = i;if( ! vis[v] ) vis[v] = 1, q.push( v );}}}return ~ lst[t]; }int MCMF() {int ans = 0;while( SPFA() ) {int flow = 1e9;for( int i = lst[t];~ i;i = lst[E[i ^ 1].to] ) flow = min( flow, E[i].flow );for( int i = lst[t];~ i;i = lst[E[i ^ 1].to] ) {E[i ^ 1].flow += flow;E[i].flow -= flow;ans += E[i].cost * flow;}}return ans; }int main() {memset( head, -1, sizeof( head ) );scanf( "%d %d", &m, &n );s = 0, t = n * (m + 1) + 1;for( int i = 1;i <= n;i ++ ) {for( int j = 1, ti;j <= m;j ++ ) {scanf( "%d", &ti );for( int k = 1;k <= n;k ++ ) //i車在k時間段被j修理addedge( i + n * m, (k - 1) * m + j, 1e9, ti * k );}}for( int i = 1;i <= n;i ++ ) addedge( s, i + n * m, 1, 0 );for( int i = 1;i <= n * m;i ++ ) addedge( i, t, 1, 0 );printf( "%.2f\n", MCMF() * 1.0 / n );return 0; }

總結

以上是生活随笔為你收集整理的[SCOI2007] 修车(费用流 + 差分时间段建图)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。