PAT1018——最短路加DFS

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

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

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

最短路+DFS

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

PAT1018——最短路加DFS
#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\n",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\n",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

 

你可能感兴趣的:(最短路)