【BZOJ】【2661】【Beijing WC2012】连连看
网络流/费用流/二分图最大权匹配
拆点费用流求最大权匹配……为什么我拿zyf和Hzwer的代码也交不过去……WA了那么多次……so sad
求路过的神牛指导啊>_<万分感谢
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //BZOJ 2661 2 #include<cmath> 3 #include<vector> 4 #include<cstdio> 5 #include<cstring> 6 #include<cstdlib> 7 #include<iostream> 8 #include<algorithm> 9 #define rep(i,n) for(int i=0;i<n;++i) 10 #define F(i,j,n) for(int i=j;i<=n;++i) 11 #define D(i,j,n) for(int i=j;i>=n;--i) 12 #define pb push_back 13 using namespace std; 14 inline int getint(){ 15 int v=0,sign=1; char ch=getchar(); 16 while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();} 17 while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();} 18 return v*sign; 19 } 20 const int N=2010,M=2000000,INF=~0u>>2; 21 typedef long long LL; 22 /******************tamplate*********************/ 23 int n,m,a,b,ans,flow; 24 inline int gcd(int a,int b){return b ? gcd(b,a%b) : a;} 25 bool judge(int x,int y){ 26 int q=x*x-y*y,s=sqrt(q); 27 if (s*s==q && gcd(y,s)==1) return 1; 28 return 0; 29 } 30 struct edge{int from,to,v,c;}; 31 struct Net{ 32 edge E[M]; 33 int head[N],next[M],cnt; 34 void ins(int x,int y,int z,int c){ 35 E[++cnt]=(edge){x,y,z,c}; 36 next[cnt]=head[x]; head[x]=cnt; 37 } 38 void add(int x,int y,int z,int c){ 39 ins(x,y,z,c); ins(y,x,0,-c); 40 } 41 int from[N],Q[M],d[N],S,T; 42 bool inq[N]; 43 bool spfa(){ 44 int l=0,r=-1; 45 F(i,0,T) d[i]=INF; 46 d[S]=0; Q[++r]=S; inq[S]=1; 47 while(l<=r){ 48 int x=Q[l++]; 49 inq[x]=0; 50 for(int i=head[x];i;i=next[i]) 51 if(E[i].v>0 && d[x]+E[i].c<d[E[i].to]){ 52 d[E[i].to]=d[x]+E[i].c; 53 from[E[i].to]=i; 54 if (!inq[E[i].to]){ 55 Q[++r]=E[i].to; 56 inq[E[i].to]=1; 57 } 58 } 59 } 60 return d[T]!=INF; 61 } 62 void mcf(){ 63 int x=INF,y,z; 64 for(int i=from[T];i;i=from[E[i].from]){ 65 // if (E[i].from==S) y=E[i].to; 66 // if (E[i].to==T) z=E[i].from-b; 67 x=min(x,E[i].v); 68 } 69 for(int i=from[T];i;i=from[E[i].from]){ 70 E[i].v-=x; 71 E[i^1].v+=x; 72 } 73 flow+=x; 74 ans+=x*d[T]; 75 } 76 void init(){ 77 scanf("%d%d",&a,&b); 78 cnt=1; S=0; T=2001; 79 F(i,a,b){ 80 add(S,i,1,0); 81 add(i+b,T,1,0); 82 F(j,a,i-1) 83 if(judge(i,j)) add(i,j+b,1,-i-j); 84 } 85 while(spfa()) mcf(); 86 printf("%d %d",flow,-ans); 87 } 88 }G1; 89 90 int main(){ 91 #ifndef ONLINE_JUDGE 92 freopen("2661.in","r",stdin); 93 freopen("2661.out","w",stdout); 94 #endif 95 G1.init(); 96 return 0; 97 }