HIT 2634 How to earn more
生活随笔
收集整理的這篇文章主要介紹了
HIT 2634 How to earn more
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
HIT_2634
? ? 將S和項目相連,容量為收益,將人和T相連,容量為雇傭的花費,然后將項目和所需的人連起來,容量為INF。實際上我們最后需要的一個結果就是這個圖的割:從S出發能到達的點就是我們要做的項目和雇傭的人,能夠到達T的點就是不必做的項目和不必雇傭的人。
? ? 因為割對應的是不做某些項目以及雇傭某些人,反映的類似“損失”的概念,因此要讓這部分“損失”最小,因此求原圖的最小割即可。
#include<stdio.h> #include<string.h> #include<algorithm> #define MAXD 210 #define MAXM 20310 #define INF 0x3f3f3f3f int M, N, first[MAXD], e, next[MAXM], v[MAXM], flow[MAXM]; int S, T, SUM, d[MAXD], q[MAXD], work[MAXD]; void add(int x, int y, int z) {v[e] = y, flow[e] = z;next[e] = first[x], first[x] = e ++; } void init() {int i, j, x, n;scanf("%d%d", &M, &N);S = 0, T = M + N + 1;memset(first, -1, sizeof(first[0]) * (T + 1));e = 0;SUM = 0;for(i = 1; i <= M; i ++){scanf("%d", &x), SUM += x;add(S, i, x), add(i, S, 0); }for(i = 1; i <= N; i ++){scanf("%d", &x);add(M + i, T, x), add(T, M + i, 0);}for(i = 1; i <= M; i ++){scanf("%d", &n);for(j = 0; j < n; j ++){scanf("%d", &x);add(i, M + 1 + x, INF), add(M + 1 + x, i, 0);}} } int bfs() {int i, j, rear = 0;memset(d, -1, sizeof(d[0]) * (T + 1));d[S] = 0, q[rear ++] = S;for(i = 0; i < rear; i ++)for(j = first[q[i]]; j != -1; j = next[j])if(flow[j] && d[v[j]] == -1){d[v[j]] = d[q[i]] + 1, q[rear ++] = v[j];if(v[j] == T) return 1; }return 0; } int dfs(int cur, int a) {if(cur == T)return a;int t;for(int &i = work[cur]; i != -1; i = next[i])if(flow[i] && d[v[i]] == d[cur] + 1)if(t = dfs(v[i], std::min(a, flow[i]))){flow[i] -= t, flow[i ^ 1] += t;return t; }return 0; } int dinic() {int ans = 0, t;while(bfs()){memcpy(work, first, sizeof(first[0]) * (T + 1));while(t = dfs(S, INF))ans += t; }return ans; } void solve() {printf("%d\n", SUM - dinic()); } int main() {int t;scanf("%d", &t);while(t --){init();solve(); }return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的HIT 2634 How to earn more的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C#ASP.NET执行BAT批处理代码
- 下一篇: Visual Studio 2010 重