zoukankan      html  css  js  c++  java
  • bzoj2661[BeiJing wc2012]连连看

    bzoj2661[BeiJing wc2012]连连看

    题意:

    给出一个闭区间[a,b]中的全部整数,如果其中某两个数x,y(设x>y)的平方差x2-y2是一个完全平方数z2,并且y与z互质,那么就可以将x和y一起消除,同时得到x+y点分数。求消除的数对尽可能多的前提下分数的最大值。

    题解:

    每个数拆成两个点,s和左侧点连流量为1,费用为0的边;右侧点和t连流量为1,费用为0的边。如果i,j合法,则同时向左侧i向右侧j及左侧j向右侧i连流量为1,费用为i+j的边。这道题和bzoj4514不同,因为每个数只出现一次,所以当左侧i和右侧j被消掉时,左侧j和右侧i也会在下一次消掉,其它的数就无法再和它们相消了。而bzoj4514每个数都有多个,可能一边没消尽,如果用这道题的做法就可能会出现另一个数把它已经被消掉的部分重复消掉,导致结果不刚好为正解的2倍。因此bzoj4514不能拆点,而这道题就可以拆点,答案就分别为算法跑出来的最大流和最大“费用”除以2。

    代码:

     1 #include <cstdio>
     2 #include <algorithm>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <queue>
     6 #define inc(i,j,k) for(int i=j;i<=k;i++)
     7 #define ll long long
     8 #define maxn 5000
     9 #define INF 0x3fffffff
    10 using namespace std;
    11 
    12 struct e{int f,t;int c,w;int n;}; e es[2000000]; int ess,g[maxn];
    13 inline void pe(int f,int t,int c,int w){
    14     es[++ess]=(e){f,t,c,w,g[f]}; g[f]=ess; es[++ess]=(e){t,f,0,-w,g[t]}; g[t]=ess;
    15 }
    16 void init(){ess=-1; memset(g,-1,sizeof(g));}
    17 queue <int> q; int d[maxn],cost,flow,fr[maxn]; bool inq[maxn],vis[maxn];
    18 bool spfa(int s,int t){
    19     while(! q.empty())q.pop(); memset(vis,0,sizeof(vis)); memset(inq,0,sizeof(inq));
    20     q.push(s); vis[s]=1; inq[s]=1; d[s]=0;
    21     while(! q.empty()){
    22         int x=q.front(); q.pop(); inq[x]=0;
    23         for(int i=g[x];i!=-1;i=es[i].n)if(es[i].c&&(!vis[es[i].t]||d[es[i].t]<d[x]+es[i].w)){
    24             vis[es[i].t]=1; d[es[i].t]=d[x]+es[i].w; fr[es[i].t]=i;
    25             if(!inq[es[i].t])q.push(es[i].t),inq[es[i].t]=1;
    26         }
    27     }
    28     if(!vis[t])return 0;else return 1;
    29 }
    30 void advanced(int s,int t){
    31     int a=INF; for(int i=t;i!=s;i=es[fr[i]].f)a=min(a,es[fr[i]].c); flow+=a;
    32     for(int i=t;i!=s;i=es[fr[i]].f)es[fr[i]].c-=a,es[fr[i]^1].c+=a,cost+=a*es[fr[i]].w;
    33 }
    34 void maxflowmaxcost(int s,int t){
    35     while(spfa(s,t))advanced(s,t);
    36 }
    37 int n,s,t,l,r;
    38 int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
    39 bool check(int x,int y){
    40     if(x<=y)return 0; double z=sqrt(x*x-y*y); if(z!=(double)((int)z))return 0;
    41     int zz=(int)z; if(gcd(y,zz)!=1)return 0; return 1;
    42 }
    43 int main(){
    44     scanf("%d%d",&l,&r); n=l-1; s=0; t=2*(r-l+1)+1;
    45     init(); inc(i,l,r)pe(s,i-n,1,0),pe(i-n+(r-l+1),t,1,0);
    46     inc(i,l,r)inc(j,l,r)if(check(i,j))pe(i-n,j-n+(r-l+1),1,i+j),pe(j-n,i-n+(r-l+1),1,i+j); maxflowmaxcost(s,t);
    47     printf("%d %d",flow>>1,cost>>1);
    48     return 0;
    49 }

    20160424

  • 相关阅读:
    phpmailer发送邮件,可以带附件
    poj 3370 鸽笼原理知识小结
    yii_wiki_145_yii-cjuidialog-for-create-new-model (通过CJuiDialog来创建新的Model)
    兄弟单词查询
    asp.net mvc3 利用Ajax实现局部刷新
    eclipse 找不到application选项
    ECharts一个强大的商业产品图表库
    多校训练hdu --Nice boat(线段树,都是泪)
    [外文理解] DDD创始人Eric Vans:要实现DDD原始意图,必须CQRS+Event Sourcing架构。
    ubuntu重新启动网卡
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5689562.html
Copyright © 2011-2022 走看看