2019 HDU 多校赛第二场 HDU 6598 Harmonious Army 构造最小割模型

题意:

有n个士兵,你可以选择让它成为战士还是法师。

有m对关系,u和v 如果同时为战士那么你可以获得a的权值

如果同时为法师,你可以获得c的权值,

如果一个为战士一个是法师,你可以获得b的权值

问你可以获得的最大权值是多少?

题解:

对每个士兵建立一个点x ,点x 向源点s 连一条边,向汇点t 连一条边,

分别表示选择两种职业,然后就可以先加上所有的贡献,通过两点关系用 最小割建模,如下图所示

设一条边的三种贡献为A, B, C,可以得到以下方程:

如果x,y都是法师,你可以获得C的权值,但是我们构建的是最小割模型(这个权值C应该是A+B+C-该图的最小割),

我们选择x,y都是法师的最小割对应的权值应该是A+B,对应的边根据上述是a,b

所以有a+b=A+B

同理对于都是战士有公式c+d=B+C

对于一战士一法师有公式a+e+d=A+C   b+e+c=A+C

存在一组解

a=b=(A+B)/2,c=d=(C+B)/2,e=-B+(A+C)/2;

为了消除浮点数的问题,我们建边的时候将边权*2,取答案的时候/2即可

  1 #include <set>
  2 #include <map>
  3 #include <stack>
  4 #include <queue>
  5 #include <cmath>
  6 #include <ctime>
  7 #include <cstdio>
  8 #include <string>
  9 #include <vector>
 10 #include <cstring>
 11 #include <iostream>
 12 #include <algorithm>
 13 #include <unordered_map>
 14
 15 #define  pi    acos(-1.0)
 16 #define  eps   1e-9
 17 #define  fi    first
 18 #define  se    second
 19 #define  rtl   rt<<1
 20 #define  rtr   rt<<1|1
 21 #define  bug                printf("******\n")
 22 #define  mem(a, b)          memset(a,b,sizeof(a))
 23 #define  name2str(x)        #x
 24 #define  fuck(x)            cout<<#x" = "<<x<<endl
 25 #define  sfi(a)             scanf("%d", &a)
 26 #define  sffi(a, b)         scanf("%d %d", &a, &b)
 27 #define  sfffi(a, b, c)     scanf("%d %d %d", &a, &b, &c)
 28 #define  sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
 29 #define  sfL(a)             scanf("%lld", &a)
 30 #define  sffL(a, b)         scanf("%lld %lld", &a, &b)
 31 #define  sfffL(a, b, c)     scanf("%lld %lld %lld", &a, &b, &c)
 32 #define  sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d)
 33 #define  sfs(a)             scanf("%s", a)
 34 #define  sffs(a, b)         scanf("%s %s", a, b)
 35 #define  sfffs(a, b, c)     scanf("%s %s %s", a, b, c)
 36 #define  sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d)
 37 #define  FIN                freopen("../in.txt","r",stdin)
 38 #define  gcd(a, b)          __gcd(a,b)
 39 #define  lowbit(x)          x&-x
 40 #define  IO                 iOS::sync_with_stdio(false)
 41
 42
 43 using namespace std;
 44 typedef long long LL;
 45 typedef unsigned long long ULL;
 46 const ULL seed = 13331;
 47 const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
 48 const int maxn = 500 + 7;
 49 const int maxm = 2e5 + 10;
 50 const int INF = 0x3f3f3f3f;
 51 const int mod = 1e9 + 7;
 52 int n, m;
 53
 54 struct MaxFlow {
 55     struct Edge {
 56         int v, nxt;
 57         LL w;
 58     } edge[maxm];
 59     int tot, num, s, t;
 60     int head[maxn];
 61
 62     void init() {
 63         memset(head, -1, sizeof(head));
 64         tot = 0;
 65     }
 66
 67     void add(int u, int v, LL w) {
 68         edge[tot] = (Edge) {
 69                 v, head[u], w
 70         };
 71         head[u] = tot++;
 72         edge[tot] = (Edge) {
 73                 u, head[v], 0
 74         };
 75         head[v] = tot++;
 76     }
 77
 78     int d[maxn], vis[maxn], gap[maxn];
 79
 80     void bfs() {
 81         memset(d, 0, sizeof(d));
 82         memset(gap, 0, sizeof(gap));
 83         memset(vis, 0, sizeof(vis));
 84         queue<int> q;
 85         q.push(t);
 86         vis[t] = 1;
 87         while (!q.empty()) {
 88             int u = q.front();
 89             q.pop();
 90             for (int i = head[u]; ~i; i = edge[i].nxt) {
 91                 int v = edge[i].v;
 92                 if (!vis[v]) {
 93                     d[v] = d[u] + 1;
 94                     gap[d[v]]++;
 95                     q.push(v);
 96                     vis[v] = 1;
 97                 }
 98             }
 99         }
100     }
101
102     int last[maxn];
103
104     LL dfs(int u, LL f) {
105         if (u == t) return f;
106         LL sap = 0;
107         for (int i = last[u]; ~i; i = edge[i].nxt) {
108             int v = edge[i].v;
109             if (edge[i].w > 0 && d[u] == d[v] + 1) {
110                 last[u] = i;
111                 LL tmp = dfs(v, min(f - sap, edge[i].w));
112                 edge[i].w -= tmp;
113                 edge[i ^ 1].w += tmp;
114                 sap += tmp;
115                 if (sap == f) return sap;
116             }
117         }
118         if (d[s] >= num) return sap;
119         if (!(--gap[d[u]])) d[s] = num;
120         ++gap[++d[u]];
121         last[u] = head[u];
122         return sap;
123     }
124
125     LL solve(int st, int ed, int n) {
126         LL flow = 0;
127         num = n;
128         s = st;
129         t = ed;
130         bfs();
131         memcpy(last, head, sizeof(head));
132         while (d[s] < num) flow += dfs(s, INFLL);
133         return flow;
134     }
135 } F;
136
137 int main() {
138     //FIN;
139     while (~sffi(n, m)) {
140         F.init();
141         LL sum = 0;
142         for (int i = 0, u, v, a, b, c; i < m; ++i) {
143             sffi(u, v);
144             sfffi(a, b, c);
145             F.add(0, u, a + b);
146             F.add(0, v, a + b);
147             F.add(u, n + 1, b + c);
148             F.add(v, n + 1, b + c);
149             F.add(u, v, -2 * b + a + c);
150             F.add(v, u, -2 * b + a + c);
151             sum += a + b + c;
152         }
153         printf("%lld\n", (2 * sum - F.solve(0, n + 1, n + 2)) / 2);
154     }
155     return 0;
156 }

原文地址:https://www.cnblogs.com/qldabiaoge/p/11406417.html

时间: 2024-10-22 07:28:01

2019 HDU 多校赛第二场 HDU 6598 Harmonious Army 构造最小割模型的相关文章

2015 多校赛 第二场 1006 (hdu 5305)

Problem Description There are n people and m pairs of friends. For every pair of friends, they can choose to become online friends (communicating using online applications) or offline friends (mostly using face-to-face communication). However, everyo

2015 多校赛 第二场 1002 (hdu 5301)

Description Your current task is to make a ground plan for a residential building located in HZXJHS. So you must determine a way to split the floor building with walls to make apartments in the shape of a rectangle. Each built wall must be paralled t

2015 多校赛 第二场 1004 hdu(5303)

Problem Description There are n apple trees planted along a cyclic road, which is L metres long. Your storehouse is built at position 0 on that cyclic road.The ith tree is planted at position xi, clockwise from position 0. There are ai delicious appl

2017 多校赛 第二场

1003.Maximum Sequence Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 0    Accepted Submission(s): 0 Problem Description Steph is extremely obsessed with “sequence problems” that are usually see

hdu 3987 Harry Potter and the Forbidden Forest【网路流最小割模型】

Harry Potter and the Forbidden Forest Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1549    Accepted Submission(s): 528 Problem Description Harry Potter notices some Death Eaters try to slip

HDU多校赛第9场 HDU 4965Fast Matrix Calculation【矩阵运算+数学小知识】

难度上,,,确实,,,不算难 问题是有个矩阵运算的优化 题目是说给个N*K的矩阵A给个K*N的矩阵B(1<=N<=1000 && 1=<K<=6),先把他们乘起来乘为C矩阵,然后算C^(N*N) 相当于 ABABABABABABAB...=(AB)^(N*N) 不如 A(BA)^(N*N-1)B 因为BA乘得K*K的矩阵,K是比较小的 #include <cstdio> #include <cstdlib> #include <cstr

HDU 5742 It&#39;s All In The Mind (贪心) 2016杭电多校联合第二场

题目:传送门. 题意:求题目中的公式的最大值,且满足题目中的三个条件. 题解:前两个数越大越好. #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; int gcd(int a,int b) { if(!b) return a; return gcd(b,a%b); } int main() { int t; ci

2014 HDU多校弟五场J题 【矩阵乘积】

题意很简单,就是两个大矩阵相乘,然后求乘积. 用 Strassen算法 的话,当N的规模达到100左右就会StackOverFlow了 况且输入的数据范围可达到800,如果变量还不用全局变量的话连内存开辟都开不出来 1 #pragma comment(linker, "/STACK:16777216") 2 #include <iostream> 3 #include <stdio.h> 4 #define ll long long 5 using namesp

多校第六场 HDU 4927 JAVA大数类

题目大意:给定一个长度为n的序列a,每次生成一个新的序列,长度为n-1,新序列b中bi=ai+1?ai,直到序列长度为1.输出最后的数. 思路:这题实在是太晕了,比赛的时候搞了四个小时,从T到WA,唉--对算组合还是不太了解啊,现在对组合算比较什么了-- import java.io.*; import java.math.*; import java.util.*; public class Main { public static void main(String[] args) { Sca