【BZOJ】【2661】【Beijing WC2012】连连看

网络流/费用流/二分图最大权匹配


  拆点费用流求最大权匹配……为什么我拿zyf和Hzwer的代码也交不过去……WA了那么多次……so sad

  求路过的神牛指导啊>_<万分感谢

 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 }
View Code

 

posted @ 2015-03-19 17:35  Tunix  阅读(336)  评论(0编辑  收藏  举报