bzoj3275: Number(最小割)

3275: Number

题目:传送门



题解:

   双倍经验@bzoj3158

  



代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define qread(x) x=read()
 7 using namespace std;
 8 const int inf=999999999;
 9 int n,st,ed,sum;
10 int A[11000],B[11000];
11 struct node
12 {
13     int x,y,c,next,other;
14 }a[3100000];int len,last[3100];
15 void ins(int x,int y,int c)
16 {
17     int k1,k2;
18     k1=++len;
19     a[len].x=x;a[len].y=y;a[len].c=c;
20     a[len].next=last[x];last[x]=len;
21
22     k2=++len;
23     a[len].x=y;a[len].y=x;a[len].c=0;
24     a[len].next=last[y];last[y]=len;
25
26     a[k1].other=k2;
27     a[k2].other=k1;
28 }
29 int list[3100],h[3100],head,tail;
30 bool bt_h()
31 {
32     memset(h,0,sizeof(h));h[st]=1;
33     list[1]=st;head=1;tail=2;
34     while(head!=tail)
35     {
36         int x=list[head];
37         for(int k=last[x];k;k=a[k].next)
38         {
39             int y=a[k].y;
40             if(h[y]==0 && a[k].c>0)
41             {
42                 h[y]=h[x]+1;
43                 list[tail++]=y;
44             }
45         }
46         head++;
47     }
48     if(h[ed]>0)return true;
49     return false;
50 }
51 int find_flow(int x,int flow)
52 {
53     if(x==ed)return flow;
54     int s=0,t;
55     for(int k=last[x];k;k=a[k].next)
56     {
57         int y=a[k].y;
58         if(h[y]==h[x]+1 && a[k].c>0 && flow>s)
59         {
60             s+=t=find_flow(y,min(a[k].c,flow-s));
61             a[k].c-=t;a[a[k].other].c+=t;
62         }
63     }
64     if(s==0)h[x]=0;
65     return s;
66 }
67 int gcd(int x,int y) {if(x>y)swap(x,y);if(x==0)return y;return gcd(y%x,x);}
68 bool pd(int x,int y)
69 {
70     int t=int(sqrt(double(x*x+y*y)));
71     if(t*t!=x*x+y*y)return true;
72     if(gcd(x,y)>1)return true;
73     return false;
74 }
75 int main()
76 {
77     freopen("number.in","r",stdin);
78     freopen("number.out","w",stdout);
79     sum=0;
80     scanf("%d",&n);
81     len=0;memset(last,0,sizeof(last));
82     for(int i=1;i<=n;i++){scanf("%d",&B[i]);sum+=B[i];}
83     st=n+1;ed=st+1;
84     for(int i=1;i<=n;i++)
85     {
86         if(B[i]%2==1)ins(st,i,B[i]);
87         else ins(i,ed,B[i]);
88     }
89     for(int i=1;i<=n;i++)
90         for(int j=1;j<=n;j++)if(i!=j)
91             if((B[i]%2==1) && (B[j]%2==0) && pd(B[i],B[j])==false)
92                 ins(i,j,999999999);
93     int ans=0;
94     while(bt_h())ans+=find_flow(st,999999999);
95     printf("%d\n",sum-ans);
96     return 0;
97 }

原文地址:https://www.cnblogs.com/CHerish_OI/p/8659290.html

时间: 2024-08-01 01:24:22

bzoj3275: Number(最小割)的相关文章

bzoj3275:最小割

看了师兄的建图方法,然后YY一下懂了一点?=>建图后即是求最小割,也就是说求最少去掉几条边就能使图不连通,图不连通意味着不会有两个相互矛盾的节点存在,若能联通的话会有两个相互矛盾的节点能够同时存在,所以=>(" S->每个奇数,每个偶数->T各连一条边, 容量为这个数字.然后不能同时选的两个数连容量为+oo的边. 总数-最大流即是答案. 因为满足a2+b2=c2的a,b一定是一奇一偶或者两个偶数, 2偶不满足gcd=1, 所以两个数不能同时选一定是一奇一偶.")

BZOJ 3275: Number( 最小割 )

--------------------------------------------------------------------- #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], *p

【BZOJ-3275&amp;3158】Number&amp;千钧一发 最小割

3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 748  Solved: 316[Submit][Status][Discuss] Description 有N个正整数,需要从中选出一些数,使这些数的和最大.若两个数a,b同时满足以下条件,则a,b不能同时被选1:存在正整数C,使a*a+b*b=c*c2:gcd(a,b)=1 Input 第一行一个正整数n,表示数的个数. 第二行n个正整数a1,a2,?an. Output

【最小割】【Dinic】bzoj3275 Number

每个点拆点,分别向源/汇连a[i]的边,满足条件的相互连INF的边,答案为sum-maxflow*2. 因为若有几个点不能同时被选,我们要贪心地选择其中和尽量大的部分,这可以由最小割来保证. #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> using namespace std; #define INF 214748364

BZOJ 3275 Number &amp;&amp; 3158 千钧一发 最小割

题目大意:给出一些数字,要求选出一些数字并保证所有数字和最大,要求这其中的数字任意两个至少满足一个条件,则不能同时被选:1.这两个数的平方和是完全平方数.2.gcd(a,b) = 1. 思路:我们可以将奇数和偶数分开来讨论,奇数不满足1,偶数不满足2,所以奇数和奇数,偶数和偶数不会互相影响.之后O(n^2)的讨论其他数字对,有影响就连边,流量正无穷,最后跑最小割最最大获利. CODE: #define _CRT_SECURE_NO_WARNINGS #include <cmath> #incl

hdoj 4289 Control 【拆点 求最小割】

Control Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2295    Accepted Submission(s): 961 Problem Description You, the head of Department of Security, recently received a top-secret informati

There is a war (hdu 2435 最小割+枚举)

There is a war Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 970    Accepted Submission(s): 277 Problem Description There is a sea. There are N islands in the sea. There are some directional

HDU 3657 Game(取数 最小割)经典

Game Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1065    Accepted Submission(s): 449 Problem Description onmylove has invented a game on n × m grids. There is one positive integer on each g

USACO 4.4 Pollutant Control (网络流求最小割割集)

Pollutant ControlHal Burch It's your first day in Quality Control at Merry Milk Makers, and already there's been a catastrophe: a shipment of bad milk has been sent out. Unfortunately, you didn't discover this until the milk was already into your del