# BZOJ 3275: Number( 最小割 )

S->每个奇数,每个偶数->T各连一条边, 容量为这个数字.然后不能同时选的两个数连容量为+oo的边. 总数-最大流即是答案.

---------------------------------------------------------------------

#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

const int maxn = 3009;
const int INF = 0x7FFFFFFF;

struct edge {
int to, cap;
edge *next, *rev;
} E[1000000], *pt = E, *head[maxn];

inline void add(int u, int v, int w) {
pt->to = v; pt->cap = w; pt->next = head[u]; head[u] = pt++;
}
inline void addedge(int u, int v, int w) {
}

edge *cur[maxn], *p[maxn];
int h[maxn], cnt[maxn], S, T, N;

int maxFlow() {
memset(cnt, 0, sizeof cnt);
memset(h, 0, sizeof h);
cnt[0] = N;
edge* e;
int flow = 0;
for(int x = S, A = INF; h[S] < N; ) {
for(e = cur[x]; e; e = e->next)
if(e->cap && h[e->to] + 1 == h[x]) break;
if(e) {
p[e->to] = cur[x] = e;
A = min(e->cap, A);
x = e->to;
if(x == T) {
for(; x != S; x = p[x]->rev->to) {
p[x]->cap -= A;
p[x]->rev->cap += A;
}
flow += A;
A = INF;
}
} else {
if(!--cnt[h[x]]) break;
h[x] = N;
for(e = head[x]; e; e = e->next) if(e->cap && h[e->to] + 1 < h[x]) {
cur[x] = e;
h[x] = h[e->to] + 1;
}
cnt[h[x]]++;
if(x != S) x = p[x]->rev->to;
}
}
return flow;
}

int num[maxn];

int gcd(int x, int y) {
return y ? gcd(y, x % y) : x;
}

bool check(int x, int y) {
int h = gcd(x, y);
if(h != 1) return false;
ll t = ll(x) * x + ll(y) * y;
t = (ll)sqrt(t);
if(t * t == ll(x) * x + ll(y) * y) return true;
return false;
}

int main() {
int n; scanf("%d", &n);
int tot = 0;
S = 0; T = n + 1; N = T + 1;
for(int i = 1; i <= n; i++) {
scanf("%d", num + i);
tot += num[i];
}
for(int i = 1; i <= n; i++) if(num[i] & 1)
for(int j = 1; j <= n; j++) if(!(num[j] & 1))
printf("%d\n", tot - maxFlow());
return 0;
}

---------------------------------------------------------------------

## 3275: Number

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 504  Solved: 222
[Submit][Status][Discuss]

## Description

1:存在正整数C，使a*a+b*b=c*c
2:gcd(a,b)=1

5
3 4 5 6 7

22

n<=3000。

## Source

posted @ 2015-09-25 14:38  JSZX11556  阅读(194)  评论(0编辑  收藏  举报