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 }