zoukankan      html  css  js  c++  java
  • Codechef July Challenge 2018 : Subway Ride

    传送门

    首先(想了很久之后)注意到一个性质:同一条边有多种颜色的话保留3种就可以了,这是因为假如最优解要求当前位置与相邻两条边都不相同,那么只要有3条边,就肯定可以满足这一点。

    完事就做一个nlogn*3^4的倍增dp就行了……实际肯定是跑不满的(而且cc机子快)。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MN 510000
    using namespace std;
    
    int n,m,l[MN],F[MN][25],_F[MN][25],v[MN][25][3][3],num=0,x,y,w,C[MN][3],de[MN];
    struct na{
        int y,w,ne;
    }b[MN<<2];
    inline void add(int x,int y,int w){b[++num].y=y;b[num].w=w;b[num].ne=l[x];l[x]=num;}
    void dfs(int x,int f){
        if (F[x][0]) return;
        F[x][0]=x;F[x][1]=f;
        for (int i=2;i<25;i++)
        if (!(F[x][i]=F[F[F[x][i-1]][i-1]][1])) break;
        _F[x][0]=f;
        for (int i=1;i<25;i++)
        if (!(_F[x][i]=_F[_F[x][i-1]][i-1])) break;
        
        for (int i=l[x];i;i=b[i].ne)
        if (b[i].y!=f){
            dfs(b[i].y,x);
            if (!C[b[i].y][0]) C[b[i].y][0]=b[i].w;else
            if (!C[b[i].y][1]) C[b[i].y][1]=b[i].w;else
            if (!C[b[i].y][2]) C[b[i].y][2]=b[i].w;
        }
    }
    void DFS(int x,int f){
        if (de[x]) return;
        de[x]=de[f]+1;
        
        for (int a=0;a<3;a++)
        for (int b=0;b<3;b++)
        if (a!=b) v[x][0][a][b]=-1e8;
        
        int tmp1,tmp2,tmp3;
        for (int i=1;i<25;i++)
        if (_F[x][i])
        for (int a=0;a<3;a++)
        if (C[x][a])
        for (int b=0;b<3;b++)
        if (C[F[x][i]][b])
        for (int A=0;A<3;A++)
        if (C[F[x][i-1]][A])
        if ((tmp1=v[x][i-1][a][A])>=0)
        for (int B=0;B<3;B++)
        if (C[_F[x][i-1]][B])
        if ((tmp2=v[_F[x][i-1]][i-1][B][b])>=0)
        if (v[x][i][a][b]<(tmp3=tmp1+tmp2+(C[F[x][i-1]][A]!=C[_F[x][i-1]][B]))) v[x][i][a][b]=tmp3;
        
        for (int i=l[x];i;i=b[i].ne)
        if (b[i].y!=x) DFS(b[i].y,x);
    }
    inline int ask(int x,int y){
        if (de[x]>de[y]) swap(x,y);
        int ans[2][3],la[2];
        memset(ans,0,sizeof(ans));
        memset(la,0,sizeof(la));
        for (int i=24;i>=0;i--)
        if (de[_F[y][i]]>=de[x]){
            if (la[1]==0){
                for (int a=0;a<3;a++)
                for (int b=0;b<3;b++)
                if (ans[1][b]<v[y][i][a][b])
                ans[1][b]=v[y][i][a][b];
                la[1]=F[y][i];
                y=_F[y][i];
            }else{
                int tmp[3]={0,0,0},TMP;
                for (int a=0;a<3;a++)
                if (C[la[1]][a])
                for (int b=0;b<3;b++)
                if (C[y][b])
                for (int c=0;c<3;c++)
                if (C[F[y][i]][c])
                if (tmp[c]<(TMP=ans[1][a]+v[y][i][b][c]+(C[la[1]][a]!=C[y][b]))) tmp[c]=TMP;
                for (int a=0;a<3;a++) ans[1][a]=tmp[a];
                
                la[1]=F[y][i];
                y=_F[y][i];
            }
        }
        if (x==y){
            int tmp=0;
            for (int a=0;a<3;a++) if (ans[1][a]>tmp) tmp=ans[1][a];
            return tmp;
        }
        int st[2]={x,y};
        for (int i=24;i>=0;i--)
        if (_F[st[0]][i]!=_F[st[1]][i]){
            for (int j=0;j<2;j++){
                if (la[j]==0){
                    for (int a=0;a<3;a++)
                    for (int b=0;b<3;b++)
                    if (ans[j][b]<v[st[j]][i][a][b])
                    ans[j][b]=v[st[j]][i][a][b];
                    la[j]=F[st[j]][i];
                    st[j]=_F[st[j]][i];
                }else{
                    int tmp[3]={-100000000,-100000000,-100000000},TMP;
                    for (int a=0;a<3;a++)
                    if (C[la[j]][a])
                    for (int b=0;b<3;b++)
                    if (C[st[j]][b])
                    for (int c=0;c<3;c++)
                    if (C[F[st[j]][i]][c])
                    if (tmp[c]<(TMP=ans[j][a]+v[st[j]][i][b][c]+(C[la[j]][a]!=C[st[j]][b]))) tmp[c]=TMP;
                    for (int a=0;a<3;a++) ans[j][a]=tmp[a];
                    
                    la[j]=F[st[j]][i];
                    st[j]=_F[st[j]][i];
                }
            }
        }
        int i=0;
            for (int j=0;j<2;j++){
                if (la[j]==0){
                    for (int a=0;a<3;a++)
                    for (int b=0;b<3;b++)
                    if (ans[j][b]<v[st[j]][i][a][b])
                    ans[j][b]=v[st[j]][i][a][b];
                    la[j]=F[st[j]][i];
                    st[j]=_F[st[j]][i];
                }else{
                    int tmp[3]={-100000000,-100000000,-100000000},TMP;
                    for (int a=0;a<3;a++)
                    if (C[la[j]][a])
                    for (int b=0;b<3;b++)
                    if (C[st[j]][b])
                    for (int c=0;c<3;c++)
                    if (C[F[st[j]][i]][c])
                    if (tmp[c]<(TMP=ans[j][a]+v[st[j]][i][b][c]+(C[la[j]][a]!=C[st[j]][b]))) tmp[c]=TMP;
                    for (int a=0;a<3;a++) ans[j][a]=tmp[a];
                    
                    la[j]=F[st[j]][i];
                    st[j]=_F[st[j]][i];
                }
            }
        int tmp=0;
        for (int a=0;a<3;a++)
        for (int b=0;b<3;b++)
        if (tmp<ans[0][a]+ans[1][b]+(C[la[0]][a]!=C[la[1]][b])) tmp=ans[0][a]+ans[1][b]+(C[la[0]][a]!=C[la[1]][b]);
        return tmp;
    }
    int main(){
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&w);
            add(x,y,w);add(y,x,w);
        }
        dfs(1,0);DFS(1,0);
        //printf(">_<%d %d %d
    ",C[3][0],C[3][1],C[3][2]);
        /*for (int i=1;i<=n;i++,puts("")){
            printf("%d:",i);
            for (int j=0;j<3;j++) printf("%d ",C[i][j]);
        }*/ 
        //printf("%d %d
    ",v[6][2][0][0],_F[6][2]);
        scanf("%d",&m);
        while(m--){
            scanf("%d%d",&x,&y);
            printf("%d
    ",ask(x,y));
        }
    }
    View Code
  • 相关阅读:
    拉钩爬取部分重写
    树莓派yolov3 测试训练结果时出现段错误或总线错误解决方法
    服务注册与发现【Eureka】- Eureka自我保护
    服务注册与发现【Eureka】- 服务发现Discovery
    服务注册与发现【Eureka】- 集群Eureka构建步骤
    服务注册与发现【Eureka】- 单机Eureka构建步骤
    服务注册与发现【Eureka】- Eureka简介
    SpringCloud正式开发前 -- 基础项目框架搭建
    服务注册与发现【Zookeeper】
    【校招】【内推】【阿里云】 ECS、神龙计算平台招聘|【经验分享】
  • 原文地址:https://www.cnblogs.com/Enceladus/p/9427433.html
Copyright © 2011-2022 走看看