bzoj2661: [BeiJing wc2012]连连看

突然发现打勾股数的表是不需要的。

但是打都打了,就不改了。

拆点,左边的点连向右边可匹配的点,然后直接费用流即可。因为对于最优解,两个数一定是相互选择的。所以答案除个2就行。

最大费用最大流把费用改成负数就可以直接用最小跑了。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;

bool mp[1100][1100];
void initmp()
{
    memset(mp,false,sizeof(mp));
    mp[5][4]=true;
    mp[5][3]=true;
    mp[13][12]=true;
    mp[13][5]=true;
    mp[17][15]=true;
    mp[17][8]=true;
    mp[25][24]=true;
    mp[25][7]=true;
    mp[29][21]=true;
    mp[29][20]=true;
    mp[37][35]=true;
    mp[37][12]=true;
    mp[41][40]=true;
    mp[41][9]=true;
    mp[53][45]=true;
    mp[53][28]=true;
    mp[61][60]=true;
    mp[61][11]=true;
    mp[65][56]=true;
    mp[65][33]=true;
    mp[65][63]=true;
    mp[65][16]=true;
    mp[73][55]=true;
    mp[73][48]=true;
    mp[85][77]=true;
    mp[85][36]=true;
    mp[85][84]=true;
    mp[85][13]=true;
    mp[89][80]=true;
    mp[89][39]=true;
    mp[97][72]=true;
    mp[97][65]=true;
    mp[101][99]=true;
    mp[101][20]=true;
    mp[109][91]=true;
    mp[109][60]=true;
    mp[113][112]=true;
    mp[113][15]=true;
    mp[125][117]=true;
    mp[125][44]=true;
    mp[137][105]=true;
    mp[137][88]=true;
    mp[145][143]=true;
    mp[145][24]=true;
    mp[145][144]=true;
    mp[145][17]=true;
    mp[149][140]=true;
    mp[149][51]=true;
    mp[157][132]=true;
    mp[157][85]=true;
    mp[169][120]=true;
    mp[169][119]=true;
    mp[173][165]=true;
    mp[173][52]=true;
    mp[181][180]=true;
    mp[181][19]=true;
    mp[185][153]=true;
    mp[185][104]=true;
    mp[185][176]=true;
    mp[185][57]=true;
    mp[193][168]=true;
    mp[193][95]=true;
    mp[197][195]=true;
    mp[197][28]=true;
    mp[205][156]=true;
    mp[205][133]=true;
    mp[205][187]=true;
    mp[205][84]=true;
    mp[221][171]=true;
    mp[221][140]=true;
    mp[221][220]=true;
    mp[221][21]=true;
    mp[229][221]=true;
    mp[229][60]=true;
    mp[233][208]=true;
    mp[233][105]=true;
    mp[241][209]=true;
    mp[241][120]=true;
    mp[257][255]=true;
    mp[257][32]=true;
    mp[265][247]=true;
    mp[265][96]=true;
    mp[265][264]=true;
    mp[265][23]=true;
    mp[269][260]=true;
    mp[269][69]=true;
    mp[277][252]=true;
    mp[277][115]=true;
    mp[281][231]=true;
    mp[281][160]=true;
    mp[289][240]=true;
    mp[289][161]=true;
    mp[293][285]=true;
    mp[293][68]=true;
    mp[305][224]=true;
    mp[305][207]=true;
    mp[305][273]=true;
    mp[305][136]=true;
    mp[313][312]=true;
    mp[313][25]=true;
    mp[317][308]=true;
    mp[317][75]=true;
    mp[325][253]=true;
    mp[325][204]=true;
    mp[325][323]=true;
    mp[325][36]=true;
    mp[337][288]=true;
    mp[337][175]=true;
    mp[349][299]=true;
    mp[349][180]=true;
    mp[353][272]=true;
    mp[353][225]=true;
    mp[365][357]=true;
    mp[365][76]=true;
    mp[365][364]=true;
    mp[365][27]=true;
    mp[373][275]=true;
    mp[373][252]=true;
    mp[377][345]=true;
    mp[377][152]=true;
    mp[377][352]=true;
    mp[377][135]=true;
    mp[389][340]=true;
    mp[389][189]=true;
    mp[397][325]=true;
    mp[397][228]=true;
    mp[401][399]=true;
    mp[401][40]=true;
    mp[409][391]=true;
    mp[409][120]=true;
    mp[421][420]=true;
    mp[421][29]=true;
    mp[425][304]=true;
    mp[425][297]=true;
    mp[425][416]=true;
    mp[425][87]=true;
    mp[433][408]=true;
    mp[433][145]=true;
    mp[445][396]=true;
    mp[445][203]=true;
    mp[445][437]=true;
    mp[445][84]=true;
    mp[449][351]=true;
    mp[449][280]=true;
    mp[457][425]=true;
    mp[457][168]=true;
    mp[461][380]=true;
    mp[461][261]=true;
    mp[481][360]=true;
    mp[481][319]=true;
    mp[481][480]=true;
    mp[481][31]=true;
    mp[485][476]=true;
    mp[485][93]=true;
    mp[485][483]=true;
    mp[485][44]=true;
    mp[493][468]=true;
    mp[493][155]=true;
    mp[493][475]=true;
    mp[493][132]=true;
    mp[505][377]=true;
    mp[505][336]=true;
    mp[505][456]=true;
    mp[505][217]=true;
    mp[509][459]=true;
    mp[509][220]=true;
    mp[521][440]=true;
    mp[521][279]=true;
    mp[533][435]=true;
    mp[533][308]=true;
    mp[533][525]=true;
    mp[533][92]=true;
    mp[541][420]=true;
    mp[541][341]=true;
    mp[545][513]=true;
    mp[545][184]=true;
    mp[545][544]=true;
    mp[545][33]=true;
    mp[557][532]=true;
    mp[557][165]=true;
    mp[565][403]=true;
    mp[565][396]=true;
    mp[565][493]=true;
    mp[565][276]=true;
    mp[569][520]=true;
    mp[569][231]=true;
    mp[577][575]=true;
    mp[577][48]=true;
    mp[593][465]=true;
    mp[593][368]=true;
    mp[601][551]=true;
    mp[601][240]=true;
    mp[613][612]=true;
    mp[613][35]=true;
    mp[617][608]=true;
    mp[617][105]=true;
    mp[625][527]=true;
    mp[625][336]=true;
    mp[629][460]=true;
    mp[629][429]=true;
    mp[629][621]=true;
    mp[629][100]=true;
    mp[641][609]=true;
    mp[641][200]=true;
    mp[653][572]=true;
    mp[653][315]=true;
    mp[661][589]=true;
    mp[661][300]=true;
    mp[673][552]=true;
    mp[673][385]=true;
    mp[677][675]=true;
    mp[677][52]=true;
    mp[685][667]=true;
    mp[685][156]=true;
    mp[685][684]=true;
    mp[685][37]=true;
    mp[689][561]=true;
    mp[689][400]=true;
    mp[689][680]=true;
    mp[689][111]=true;
    mp[697][528]=true;
    mp[697][455]=true;
    mp[697][672]=true;
    mp[697][185]=true;
    mp[701][651]=true;
    mp[701][260]=true;
    mp[709][660]=true;
    mp[709][259]=true;
    mp[725][627]=true;
    mp[725][364]=true;
    mp[725][644]=true;
    mp[725][333]=true;
    mp[733][725]=true;
    mp[733][108]=true;
    mp[745][624]=true;
    mp[745][407]=true;
    mp[745][713]=true;
    mp[745][216]=true;
    mp[757][595]=true;
    mp[757][468]=true;
    mp[761][760]=true;
    mp[761][39]=true;
    mp[769][600]=true;
    mp[769][481]=true;
    mp[773][748]=true;
    mp[773][195]=true;
    mp[785][736]=true;
    mp[785][273]=true;
    mp[785][783]=true;
    mp[785][56]=true;
    mp[793][665]=true;
    mp[793][432]=true;
    mp[793][775]=true;
    mp[793][168]=true;
    mp[797][572]=true;
    mp[797][555]=true;
    mp[809][759]=true;
    mp[809][280]=true;
    mp[821][700]=true;
    mp[821][429]=true;
    mp[829][629]=true;
    mp[829][540]=true;
    mp[841][840]=true;
    mp[841][41]=true;
    mp[845][836]=true;
    mp[845][123]=true;
    mp[845][837]=true;
    mp[845][116]=true;
    mp[853][828]=true;
    mp[853][205]=true;
    mp[857][825]=true;
    mp[857][232]=true;
    mp[865][703]=true;
    mp[865][504]=true;
    mp[865][816]=true;
    mp[865][287]=true;
    mp[877][805]=true;
    mp[877][348]=true;
    mp[881][800]=true;
    mp[881][369]=true;
    mp[901][780]=true;
    mp[901][451]=true;
    mp[901][899]=true;
    mp[901][60]=true;
    mp[905][663]=true;
    mp[905][616]=true;
    mp[905][777]=true;
    mp[905][464]=true;
    mp[925][756]=true;
    mp[925][533]=true;
    mp[925][924]=true;
    mp[925][43]=true;
    mp[929][920]=true;
    mp[929][129]=true;
    mp[937][912]=true;
    mp[937][215]=true;
    mp[941][741]=true;
    mp[941][580]=true;
    mp[949][851]=true;
    mp[949][420]=true;
    mp[949][900]=true;
    mp[949][301]=true;
    mp[953][728]=true;
    mp[953][615]=true;
    mp[965][884]=true;
    mp[965][387]=true;
    mp[965][957]=true;
    mp[965][124]=true;
    mp[977][945]=true;
    mp[977][248]=true;
    mp[985][697]=true;
    mp[985][696]=true;
    mp[985][864]=true;
    mp[985][473]=true;
    mp[997][925]=true;
    mp[997][372]=true;
}

struct node
{
    int x,y,c,d,next,other;
}a[410000];int len,last[110000];
void ins(int x,int y,int c,int d)
{
    int k1,k2;
    
    len++;k1=len;
    a[len].x=x;a[len].y=y;a[len].c=c;a[len].d=d;
    a[len].next=last[x];last[x]=len;
    
    len++;k2=len;
    a[len].x=y;a[len].y=x;a[len].c=0;a[len].d=-d;
    a[len].next=last[y];last[y]=len;
    
    a[k1].other=k2;
    a[k2].other=k1;
}

int flow,mmax;
int st,ed;
int d[110000],list[110000];bool v[110000];
int pos[110000],c[110000];
bool bfs()
{
    memset(d,63,sizeof(d));d[st]=0;
    memset(v,false,sizeof(v));v[st]=true;
    
    int head=1,tail=2;
    list[1]=st;pos[st]=0;c[st]=2147483647;
    while(head!=tail)
    {
        int x=list[head];
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(a[k].c>0&&d[y]>d[x]+a[k].d)
            {
                d[y]=d[x]+a[k].d;
                pos[y]=k;
                c[y]=min(a[k].c,c[x]);
                if(v[y]==false)
                {
                    v[y]=true;
                    list[tail]=y;
                    tail++;if(tail==105000)tail=1;
                }
            }
        }
        v[x]=false;
        head++;if(head==105000)head=1;
    }
    if(d[ed]>999999999)return false;
    else
    {
        flow+=c[ed];
        mmax+=d[ed]*c[ed];
        int y=ed;
        while(pos[y]!=0)
        {
            int k=pos[y];
            a[k].c-=c[ed];
            a[a[k].other].c+=c[ed];
            y=a[k].x;
        }
        return true;
    }
}
int main()
{
    initmp();
    int L,R;
    scanf("%d%d",&L,&R);
    len=0;memset(last,0,sizeof(last));
    for(int i=L;i<=R;i++)
        for(int j=L;j<=R;j++)
            if(mp[i][j]==true||mp[j][i]==true)
                ins((i-L+1),(j-L+1)+(R-L+1),1,-(i+j));
    st=(R-L+1)*2+1,ed=(R-L+1)*2+2;
    for(int i=L;i<=R;i++) ins(st,(i-L+1),1,0), ins((i-L+1)+(R-L+1),ed,1,0);
    //composition
    
    flow=0;mmax=0;
    while(bfs()==true);
    printf("%d %d\n",flow/2,-mmax/2);
    return 0;
}

 

posted @ 2018-02-27 13:58  AKCqhzdy  阅读(231)  评论(0编辑  收藏  举报