您的位置:首页 > 其它

BZOJ 2661 连连看

2016-06-24 21:43 246 查看
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

#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iostream>
#define inf 1000000
int l,r,pd[10000005],L[200005],R[200005],cnt,sz,b[200005];
int tot,go[200005],next[200005],first[200005],cost[200005],flow[200005];
int op[200005],dis[200005],c[200005],vis[200005],edge[200005],from[200005];
int S,T,ans1,ans2;
int gcd(int a,int b){if (b==0) return a;else return gcd(b,a%b);}
int read(){
char ch=getchar();int t=0,f=1;
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
return t*f;
}
void insert(int x,int y,int z,int l){
tot++;
go[tot]=y;
next[tot]=first[x];
first[x]=tot;
flow[tot]=z;
cost[tot]=l;
}
void add(int x,int y,int z,int l){
insert(x,y,z,l);op[tot]=tot+1;
insert(y,x,0,-l);op[tot]=tot-1;
}
bool spfa(){
for (int i=0;i<=T;i++)
dis[i]=inf,vis[i]=0;
int h=1,t=1;c[1]=S;vis[S]=1;dis[S]=0;
while (h<=t){
int now=c[h++];
for (int i=first[now];i;i=next[i]){
int pur=go[i];
if (dis[pur]>dis[now]+cost[i]&&flow[i]){
dis[pur]=dis[now]+cost[i];
edge[pur]=i;
from[pur]=now;
if (vis[pur]) continue;
vis[pur]=1;
c[++t]=pur;
}
}
vis[now]=0;
}
return dis[T]!=inf;
}
void updata(){
int mn=0x3f3f3f3f;
for (int i=T;i!=S;i=from[i]){
mn=std::min(mn,flow[edge[i]]);
}
for (int i=T;i!=S;i=from[i]){
ans2+=mn*cost[edge[i]];
flow[edge[i]]-=mn;
flow[op[edge[i]]]+=mn;
}
ans1+=mn;
}
int main(){
l=read();r=read();
if (l>r) std::swap(l,r);
for (int i=1;i<=1000;i++) pd[i*i]=i;
for (int j=l;j<=r;j++)
for (int i=j+1;i<=r;i++){
int k=i*i-j*j;
if (pd[k]&&gcd(pd[k],j)==1){
b[i]=b[j]=1;
cnt++;
L[cnt]=j;
R[cnt]=i;
}
}
for (int i=l;i<=r;i++)
if (b[i])
b[i]=++sz;
S=0;T=sz+sz+1;
for (int i=l;i<=r;i++)
if (b[i])
add(S,b[i],1,0),add(b[i]+sz,T,1,0);
for (int i=1;i<=cnt;i++){
add(b[L[i]],b[R[i]]+sz,1,inf-L[i]-R[i]);
add(b[R[i]],b[L[i]]+sz,1,inf-L[i]-R[i]);
}
while (spfa()) updata();
printf("%d ",ans1/2);
printf("%d\n",(ans1*inf-ans2)/2);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: