1. 程式人生 > >BZOJ1221 [HNOI2001]軟件開發 - 費用流

BZOJ1221 [HNOI2001]軟件開發 - 費用流

++i tmp != getch ati $0 每天 har cor

題解

非常顯然的費用流。 但是建圖還是需要思考的QuQ

將每天分成兩個節點 $x_{i,1}, x_{i,2} $, $ x_{i,1}$用於提供服務, $x_{i ,2}$ 用來從源點獲得$nd[i] $個毛巾進行消毒(因為$x_{i ,1} $已經流向匯點)。

1、 源點向$x_{i,1} $連容量為$inf$, 費用為$f$ 的邊, 表示給買毛巾。

2、 $x_{i, 1}$向匯點連容量為$nd[ i ]$ , 費用為$0 $的邊, 表示提供服務

3、$x_{i, 1}$ 向$x_{i + 1, 1}$ 連容量為$inf$, 費用為$0$ 的邊, 表示毛巾存到下一天用

4、 源點向$x_{i, 2}$連容量為$nd[ i ]$, 費用為$0 $的邊, 表示用過的毛巾拿去清洗

5、$x_{i , 2 }$ 向 $x_{i + a + 1, 1}$連容量為$inf$, 費用為$fa$ 的邊, 表示通過方式$a$清洗

6、同理5

然後跑費用流, 就可以把題秒啦

代碼

技術分享圖片
 1 #include<cstring>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<queue>
 5 #define rd read()
 6 #define rep(i,a,b) for(int i = (a); i <= (b); ++i)
 7
using namespace std; 8 9 const int N = 1e4; 10 const int inf = 1061109567; 11 12 int n, dis[N], pre[N], vis[N], a, b, f, fa, fb, nd[N]; 13 int head[N], tot, maxflow, minco; 14 int S, T = N - 1; 15 16 queue<int>q; 17 18 struct edge { 19 int nxt, to, val, c; 20 }e[N << 1
]; 21 22 int read() { 23 int X = 0, p = 1; char c = getchar(); 24 for(; c > 9 || c < 0; c = getchar()) if(c == -) p = -1; 25 for(; c >= 0 && c <= 9; c = getchar()) X = X * 10 + c - 0; 26 return X * p; 27 } 28 29 void added(int fr, int to, int val, int c) { 30 e[++tot].to = to; 31 e[tot].val = val; 32 e[tot].c = c; 33 e[tot].nxt = head[fr]; 34 head[fr] = tot; 35 } 36 37 void add(int fr, int to, int val, int c) { 38 added(fr, to, val ,c); 39 added(to, fr, 0, -c); 40 } 41 42 int ch(int x) { 43 return ((x + 1) ^ 1) - 1; 44 } 45 46 int bfs() { 47 memset(dis, 63, sizeof(dis)); 48 memset(vis, 0, sizeof(vis)); 49 memset(pre, 0, sizeof(pre)); 50 q.push(S); 51 dis[S] = 0; 52 vis[S] = 1; 53 for(int u, nt; !q.empty(); ) { 54 u = q.front(); q.pop(); 55 for(int i =head[u]; i; i = e[i].nxt) { 56 nt = e[i].to; 57 if(dis[nt] <= dis[u] + e[i].c || !e[i].val) continue; 58 dis[nt] = dis[u] + e[i].c; 59 pre[nt] = i; 60 if(!vis[nt]) vis[nt] = 1, q.push(nt); 61 } 62 vis[u] = 0; 63 } 64 return dis[T]; 65 } 66 67 void EK() { 68 for(; bfs() != inf; ) { 69 int tmp = inf; 70 for(int i = pre[T]; i; i = pre[e[ch(i)].to]) tmp = min(tmp, e[i].val); 71 for(int i = pre[T]; i; i = pre[e[ch(i)].to]) e[i].val -= tmp, e[ch(i)].val += tmp; 72 maxflow += tmp; 73 minco += tmp * dis[T]; 74 } 75 } 76 77 int main() 78 { 79 n = rd; a = rd; b = rd; f = rd; fa = rd; fb = rd; 80 rep(i, 1, n) nd[i] = rd; 81 rep(i, 1, n) { 82 add(S, i, inf, f); 83 add(S, i + n, nd[i], 0); 84 add(i, T, nd[i], 0); 85 if(i < n) add(i, i + 1, inf, 0); 86 if(i + a < n) add(i + n, i + a + 1, nd[i], fa); 87 if(i + b < n) add(i + n, i + b + 1, nd[i], fb); 88 } 89 EK(); 90 printf("%d\n", minco); 91 }
View Code

BZOJ1221 [HNOI2001]軟件開發 - 費用流