• PAT1018——最短路加DFS


    http://pat.zju.edu.cn/contests/pat-a-practise/1018

    在杭州各个点,有很多自助自行车的点,最大容纳点为CMAX,但比较适合的情况是CMAX/2,

    现在从起点到终点,在最短路的情况下,调整各个车站的自行车数量使之CMAX/2,问开始时要提供的自行车最少与最后剩余的自行车最少的路径

    最短路+DFS

    在DFS时加上一个剪枝 if(lenth>dis[first])return ;就可以通过所有点

    #include<stdio.h>
    #define MAX 0x3ffffff
    int cmax,N,end,M;
    int node[599];
    int map[599][599];
    int path[599];
    
    int rpath[599];
    int in,out,nowstep,rstep;
    
    bool hash[599][599];
    int shortlen;
    
    int dis[505];
    bool use[505];
    int ok=0;
    
    
    void dijk( )
    {
        int n=N,m;
        int min,rj,i,j;
        for(j=0;j<=n;j++)
        {
            dis[j]=map[0][j];
            use[j]=0;
        }
        use[0]=1;
        for(i=0;i<n;i++)
        {
            min=MAX;
            for(j=0;j<=n;j++)
            {
                if(use[j]==1)continue;
                if(dis[j]<min)
                {
                    min=dis[j];
                    rj=j;
                }
            }
            
            use[rj]=1;
            for(j=0;j<=n;j++)
            {
                if(use[j]==1)continue;
                if(dis[j]>dis[rj]+map[rj][j])
                    dis[j]=dis[rj]+map[rj][j];
            }
        }
    
        shortlen=dis[end];
    }
    
    
    void print(){
        int i;
        printf("%d",in);
        printf(" 0");
        for(i=1;i<=rstep;i++){
            printf("->%d",rpath[i]);
        }
        printf(" %d
    ",out);
    }
    
    void cal(){
        int tin=99999999,tout=999999999;
        int i,add=0;
        for(i=1;i<=nowstep;i++){
            add+=node[path[i]]-cmax/2;
            if(add<tin)tin=add;
        }
        if(tin>0)tin=0;
        else tin=-tin;
        tout=add+tin;
    
        if((tin<in)||((tin==in)&&tout<out)){
            in=tin;
            out=tout;
            if(in==0&&tout==0)ok=1;
            rstep=nowstep;
            for(i=1;i<=nowstep;i++){
                rpath[i]=path[i];
            }
        }
    
        //test
        /*
        printf("%d",tin);
        printf(" 0");
        for(i=1;i<=nowstep;i++){
            printf("->%d",path[i]);
        }
        printf(" %d
    ",tout);
        */
    }
    void dfs(int step,int first,int lenth)
    {
        if(ok==1||lenth>dis[first])return ; //lenth>dis[first] 是个关键的剪枝,不加的话最后一个点会超时
        if(lenth==shortlen&&first==end){
            nowstep=step;
            cal();
        }
    
        int j;
        for(j=1;j<=N;j++){
            if(hash[first][j]==1||map[j][first]==MAX)continue;
            hash[first][j]=hash[j][first]=1;
            path[step+1]=j;
            dfs(step+1,j,lenth+map[first][j]);
            hash[first][j]=hash[j][first]=0;
        }
    }
    
    int main()
    {
        while(scanf("%d%d%d%d",&cmax,&N,&end,&M)!=EOF){
            int i,j,temp;
            ok=0;
            in=99999999;
            out=99999999;
    
            for(i=0;i<=N;i++){
                for(j=0;j<=N;j++){
                    map[i][j]=MAX;
                    hash[i][j]=0;
                }
            }
    
            for(i=1;i<=N;i++){
                scanf("%d",&node[i]);
            }
            
    
            int ll,rr,v;
            for(i=1;i<=M;i++){
                scanf("%d%d%d",&ll,&rr,&v);
                map[ll][rr]=map[rr][ll]=v;
            }
            dijk();
            dfs(0,0,0);
            print();
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    Codeforces G. Ciel the Commander
    点分治模板
    Codeforces I. Vessels(跳转标记)
    Codeforces C. Maximum Value(枚举二分)
    Codeforces D. Little Elephant and Interval(思维找规律数位dp)
    [USACO15DEC]最大流Max Flow(树上差分)
    Codeforces E. Alyona and a tree(二分树上差分)
    一致性Hash算法
    零拷贝
    Maven 指定范围依赖
  • 原文地址:https://www.cnblogs.com/huhuuu/p/3340327.html
Copyright © 2020-2023  润新知