您的位置:首页 > 其它

[UVALive 7264] Kejin Game(最小割)

2017-05-07 22:26 288 查看
题目链接:https://vjudge.net/problem/UVALive-7264

题意:点技能点,每个技能点有前置技能点,也可能没有。每点一个技能点需要一个花费,还可以通过氪金跳过某点的前置技能点,直接点这个技能。问点到期望的一个技能点的总花费最小是多少。

假如只将这个点与超级汇相连,那就是求一个割边集。求最小花费就是求最小割,也就是求最大流。

关于点技能点的花费,则需要将这个技能点拆成两个点,在边上设置容量即可。

对于原图的技能树关系,则照搬出点->入点即可。

从源点连接到各个点的入点即可,期望点连接汇点,容量为inf即可。

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 typedef struct Edge {
5     int u, v, w, next;
6 }Edge;
7
8 const int inf = 0x7f7f7f7f;
9 const int maxn = 1010;
10
11 int cnt, dhead[maxn];
12 int cur[maxn], dd[maxn];
13 Edge dedge[1000100];
14 int S, T, N;
15
16 void init() {
17     memset(dhead, -1, sizeof(dhead));
18     for(int i = 0; i < maxn; i++) dedge[i].next = -1;
19     S = 0; cnt = 0;
20 }
21
22 void adde(int u, int v, int w, int c1=0) {
23     dedge[cnt].u = u; dedge[cnt].v = v; dedge[cnt].w = w;
24     dedge[cnt].next = dhead[u]; dhead[u] = cnt++;
25     dedge[cnt].u = v; dedge[cnt].v = u; dedge[cnt].w = c1;
26     dedge[cnt].next = dhead[v]; dhead[v] = cnt++;
27 }
28
29 bool bfs(int s, int t, int n) {
30     queue<int> q;
31     for(int i = 0; i < n; i++) dd[i] = inf;
32     dd[s] = 0;
33     q.push(s);
34     while(!q.empty()) {
35         int u = q.front(); q.pop();
36         for(int i = dhead[u]; ~i; i = dedge[i].next) {
37             if(dd[dedge[i].v] > dd[u] + 1 && dedge[i].w > 0) {
38                 dd[dedge[i].v] = dd[u] + 1;
39                 if(dedge[i].v == t) return 1;
40                 q.push(dedge[i].v);
41             }
42         }
43     }
44     return 0;
45 }
46
47 int dinic(int s, int t, int n) {
48     int st[maxn], top;
49     int u;
50     int flow = 0;
51     while(bfs(s, t, n)) {
52         for(int i = 0; i < n; i++) cur[i] = dhead[i];
53         u = s; top = 0;
54         while(cur[s] != -1) {
55             if(u == t) {
56                 int tp = inf;
57                 for(int i = top - 1; i >= 0; i--) {
58                     tp = min(tp, dedge[st[i]].w);
59                 }
60                 flow += tp;
61                 for(int i = top - 1; i >= 0; i--) {
62                     dedge[st[i]].w -= tp;
63                     dedge[st[i] ^ 1].w += tp;
64                     if(dedge[st[i]].w == 0) top = i;
65                 }
66                 u = dedge[st[top]].u;
67             }
68             else if(cur[u] != -1 && dedge[cur[u]].w > 0 && dd[u] + 1 == dd[dedge[cur[u]].v]) {
69                 st[top++] = cur[u];
70                 u = dedge[cur[u]].v;
71             }
72             else {
73                 while(u != s && cur[u] == -1) {
74                     u = dedge[st[--top]].u;
75                 }
76                 cur[u] = dedge[cur[u]].next;
77             }
78         }
79     }
80     return flow;
81 }
82
83 int n, m, s;
84
85 int main() {
86     // freopen("in", "r", stdin);
87     int TT;
88     int u, v, w;
89     scanf("%d", &TT);
90     while(TT--) {
91         init();
92         scanf("%d%d%d",&n,&m,&s);
93         S = 0, T = 2 * n + 1, N = T + 1;
94         for(int i = 0; i < m; i++) {
95             scanf("%d%d%d",&u,&v,&w);
96             adde(u+n, v, w);
97         }
98         for(int i = 1; i <= n; i++) {
99             scanf("%d", &w);
100             adde(S, i, w);
101         }
102         for(int i = 1; i <= n; i++) {
103             scanf("%d", &w);
104             adde(i, i+n, w);
105         }
106         adde(s+n, T, inf);
107         printf("%d\n", dinic(S, T, N));
108     }
109     return 0;
110 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: