首页 > 代码库 > BZOJ 3158: 千钧一发
BZOJ 3158: 千钧一发
3158: 千钧一发
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1201 Solved: 446
[Submit][Status][Discuss]
Description
Input
第一行一个正整数N。
第二行共包括N个正整数,第 个正整数表示Ai。
第三行共包括N个正整数,第 个正整数表示Bi。
Output
共一行,包括一个正整数,表示在合法的选择条件下,可以获得的能量值总和的最大值。
Sample Input
4
3 4 5 12
9 8 30 9
Sample Output
39
HINT
1<=N<=1000,1<=Ai,Bi<=10^6
Source
Katharon+#1
网络流求最小割,很机智的建图方式。
发现可以把数字按照奇偶性分类,奇数一定满足1条件,偶数一定满足2条件,WOC,然后就二分图了?
暴力判断奇数和偶数是否不能在同一集合中,如不能在同一集合,在其中加一天正无穷的边,表示不可割。
其余点按奇偶性分别向S,T连bi的边即可,Σbi - 最小割就是最终答案。
1 #include <cmath> 2 #include <cstdio> 3 #include <cstring> 4 5 typedef long long lnt; 6 7 const int siz = 1000005; 8 const int inf = 1000000007; 9 10 int n; 11 int a[siz]; 12 int b[siz]; 13 14 int tot; 15 int s, t; 16 int hd[siz]; 17 int to[siz]; 18 int fl[siz]; 19 int nt[siz]; 20 21 inline void add(int u, int v, int f) 22 { 23 nt[tot] = hd[u]; to[tot] = v; fl[tot] = f; hd[u] = tot++; 24 nt[tot] = hd[v]; to[tot] = u; fl[tot] = 0; hd[v] = tot++; 25 } 26 27 int dep[siz]; 28 29 inline bool bfs(void) 30 { 31 static int que[siz]; 32 static int head, tail; 33 34 memset(dep, 0, sizeof(dep)); 35 head = 0, tail = 0; 36 que[tail++] = s; 37 dep[s] = 1; 38 39 while (head != tail) 40 { 41 int u = que[head++], v; 42 43 for (int i = hd[u]; ~i; i = nt[i]) 44 if (!dep[v = to[i]] && fl[i]) 45 dep[que[tail++] = v] = dep[u] + 1; 46 } 47 48 return dep[t]; 49 } 50 51 int cur[siz]; 52 53 int min(int a, int b) 54 { 55 return a < b ? a : b; 56 } 57 58 int dfs(int u, int f) 59 { 60 if (u == t || !f) 61 return f; 62 63 int used = 0, flow, v; 64 65 for (int i = cur[u]; ~i; i = nt[i]) 66 if (dep[v = to[i]] == dep[u] + 1 && fl[i]) 67 { 68 flow = dfs(v, min(f - used, fl[i])); 69 70 used += flow; 71 fl[i] -= flow; 72 fl[i^1] += flow; 73 74 if (used == f) 75 return f; 76 77 if (fl[i]) 78 cur[u] = i; 79 } 80 81 if (!used) 82 dep[u] = 0; 83 84 return used; 85 } 86 87 inline int maxFlow(void) 88 { 89 int maxFlow = 0, newFlow; 90 91 while (bfs()) 92 { 93 for (int i = s; i <= t; ++i) 94 cur[i] = hd[i]; 95 96 while (newFlow = dfs(s, inf)) 97 maxFlow += newFlow; 98 } 99 100 return maxFlow;101 }102 103 inline lnt sqr(lnt x)104 {105 return x * x;106 }107 108 int gcd(int x, int y)109 {110 return y ? gcd(y, x % y) : x;111 }112 113 inline bool check(int x, int y)114 {115 if (gcd(x, y) != 1)116 return false;117 118 lnt t = sqr(x) + sqr(y);119 if (sqr(sqrt(t)) != t)120 return false;121 122 return true;123 }124 125 signed main(void)126 {127 scanf("%d", &n);128 129 for (int i = 1; i <= n; ++i)130 scanf("%d", a + i);131 132 for (int i = 1; i <= n; ++i)133 scanf("%d", b + i);134 135 s = 0, t = n + 1;136 137 memset(hd, -1, sizeof(hd));138 139 for (int i = 1; i <= n; ++i)140 if (a[i] & 1)141 add(s, i, b[i]);142 else143 add(i, t, b[i]);144 145 for (int i = 1; i <= n; ++i)146 for (int j = 1; j <= n; ++j)147 if (a[i] & 1)if (!(a[j] & 1))148 if (check(a[i], a[j]))149 add(i, j, inf);150 151 int sum = 0;152 153 for (int i = 1; i <= n; ++i)154 sum += b[i];155 156 printf("%d\n", sum - maxFlow());157 }
@Author: YouSiki
BZOJ 3158: 千钧一发
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。