BZOJ 2661 连连看

http://www.lydsy.com/JudgeOnline/problem.php?id=2661

思路:预处理出每个数字,然后若有x^2=y^2+z^2且z与y互质,

s->x 1 ,0

x+n-> t 1 , 0

x->y+n -> 1 , inf-x-y

y->x+n-> 1 ,inf-x-y

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 #define inf 1000000
 7 int l,r,pd[10000005],L[200005],R[200005],cnt,sz,b[200005];
 8 int tot,go[200005],next[200005],first[200005],cost[200005],flow[200005];
 9 int op[200005],dis[200005],c[200005],vis[200005],edge[200005],from[200005];
10 int S,T,ans1,ans2;
11 int gcd(int a,int b){if (b==0) return a;else return gcd(b,a%b);}
12 int read(){
13     char ch=getchar();int t=0,f=1;
14     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
15     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
16     return t*f;
17 }
18 void insert(int x,int y,int z,int l){
19     tot++;
20     go[tot]=y;
21     next[tot]=first[x];
22     first[x]=tot;
23     flow[tot]=z;
24     cost[tot]=l;
25 }
26 void add(int x,int y,int z,int l){
27     insert(x,y,z,l);op[tot]=tot+1;
28     insert(y,x,0,-l);op[tot]=tot-1;
29 }
30 bool spfa(){
31     for (int i=0;i<=T;i++)
32      dis[i]=inf,vis[i]=0;
33     int h=1,t=1;c[1]=S;vis[S]=1;dis[S]=0;
34     while (h<=t){
35         int now=c[h++];
36         for (int i=first[now];i;i=next[i]){
37             int pur=go[i];
38             if (dis[pur]>dis[now]+cost[i]&&flow[i]){
39                 dis[pur]=dis[now]+cost[i];
40                 edge[pur]=i;
41                 from[pur]=now;
42                 if (vis[pur]) continue;
43                 vis[pur]=1;
44                 c[++t]=pur;
45             }
46         }
47         vis[now]=0;
48     }
49     return dis[T]!=inf;
50 }
51 void updata(){
52     int mn=0x3f3f3f3f;
53     for (int i=T;i!=S;i=from[i]){
54         mn=std::min(mn,flow[edge[i]]);
55     }
56     for (int i=T;i!=S;i=from[i]){
57         ans2+=mn*cost[edge[i]];
58         flow[edge[i]]-=mn;
59         flow[op[edge[i]]]+=mn;
60     }
61     ans1+=mn;
62 }
63 int main(){
64     l=read();r=read();
65     if (l>r) std::swap(l,r);
66     for (int i=1;i<=1000;i++) pd[i*i]=i;
67     for (int j=l;j<=r;j++)
68      for (int i=j+1;i<=r;i++){
69             int k=i*i-j*j;
70             if (pd[k]&&gcd(pd[k],j)==1){
71                 b[i]=b[j]=1;
72                 cnt++;
73                 L[cnt]=j;
74                 R[cnt]=i;
75             }
76      }
77     for (int i=l;i<=r;i++)
78      if (b[i])
79       b[i]=++sz;
80     S=0;T=sz+sz+1;
81     for (int i=l;i<=r;i++)
82      if (b[i])
83       add(S,b[i],1,0),add(b[i]+sz,T,1,0);
84     for (int i=1;i<=cnt;i++){
85         add(b[L[i]],b[R[i]]+sz,1,inf-L[i]-R[i]);
86         add(b[R[i]],b[L[i]]+sz,1,inf-L[i]-R[i]);
87     }   
88     while (spfa()) updata();
89     printf("%d ",ans1/2);
90     printf("%d\n",(ans1*inf-ans2)/2);
91 }

 

posted @ 2016-06-24 21:43  GFY  阅读(138)  评论(0编辑  收藏  举报