zoukankan      html  css  js  c++  java
  • hdu 2962 题解

    题目

    题意

    给出一张图,每条道路有限高,给出车子的起点,终点,最高高度,问在保证高度尽可能高的情况下的最短路,如果不存在输出 $ cannot reach destination $

    跟前面 $ hdu5418 $ 一样的,题目挺基础的,但是在细节方面比较抠。要是最高度尽可能高,我们就可以想去枚举可能的高度去跑 $ spfa $ ,但我们可以发现这样效率太低了,那么我们为什么不二分答案呢?给出最高高度了,最低不就是 $ 0 $ 吗?二分答案再去跑 $ spfa $ 加上限制条件。 这题时限 $ 10s $ 枚举其实一样能过,也跑得挺快的。另外我还敲了敲 $ floyd $ 果不其然,数据范围太大,它挂了。dijkstra它我也敲挂了(答案错误)等改对了再说吧。

    比较坑的点:每组答案之间输出换行,因为这个格式错误了好几次。

    代码(按时间从小到大排序

    dijkstra(堆优化)+二分

    $ 187MS $

    /*
    dijkstra(堆优化)+二分
    Judge Status:Accepted
    Exe.Time:187MS	
    Exe.Memory:1752K
    Code Len:2640 B
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    const int M=1000010;
    const int INF=0x3f3f3f3f;
    struct node{
        int h;
        int data;
    }edge[M];
    int head[N],ver[M],Next[M],ans,minf,n,m,tot,star,en,sum,addmin;
    void add(int x,int y,int z,int hi){
        ver[++tot]=y;edge[tot].data=z;edge[tot].h=hi;Next[tot]=head[x];head[x]=tot;
    }
    struct nod{
    	int data;
    	int num;
    }minn[M];
    int d[N];
    bool book[N];
    void shiftdownmin(int x){
        int t,flag=0;
        while(x*2<=addmin&&flag==0){
            if(minn[x].data>minn[x*2].data)t=x*2;
            else t=x;
            if(x*2+1<=addmin){
                if(minn[t].data>minn[x*2+1].data)t=x*2+1;
            }
            if(t!=x){
                swap(minn[t],minn[x]);
                x=t;
            }else flag=1;
        }
    }
    void shiftupmin(int x) {
        int flag=0; 
        if(x==1) return; 
        while(x!=1&&flag==0){
            if(minn[x].data<minn[x/2].data) swap(minn[x],minn[x/2]);
            else flag=1;
            x=x/2;
        }
    }
    void dijkstra(int mi){
    	memset(book,0,sizeof(book));
    	memset(d,0x3f,sizeof(d));addmin=0;
    	d[star]=0;
        minn[++addmin].data=0;
        minn[addmin].num=star;
        while(addmin){
            int x=minn[1].num;
    		minn[1]=minn[addmin--];
    		shiftdownmin(1);
            if(book[x]) continue;
            book[x]=1;
            for(int i=head[x];i;i=Next[i]){
                int y=ver[i],z=edge[i].data;
                if(d[y]>d[x]+z&&edge[i].h>=mi){
                    d[y]=d[x]+z;
                    minn[++addmin].num=y;
                    minn[addmin].data=d[y];
                    shiftupmin(addmin);
                }
            }
        }
    }
    int main(){
        while(scanf("%d %d",&n,&m)){
            if((!n)&&(!m)) return 0;
            if(sum) printf("
    ");
            memset(head,0,sizeof(head));tot=0;sum++;
            int l=0,r=0;
            for(int i=1;i<=m;++i){
                int x,y,z,h;
                scanf("%d %d %d %d",&x,&y,&h,&z);
                if(h==-1) h=INF;
                add(x,y,z,h);
                add(y,x,z,h);
            }scanf("%d %d %d",&star,&en,&r);
            ans=0;minf=0;
            while(l<=r){
            	int mid=(l+r)>>1;
            	dijkstra(mid);
                if(d[en]!=INF){
                    if(mid>ans){
                    	ans=mid;
                    	minf=d[en];
                    } l=mid+1;
            	}else r=mid-1;
            }
            printf("Case %d:
    ",sum);
            if(ans!=0){
                printf("maximum height = %d
    ",ans);
                printf("length of shortest route = %d
    ",minf);
            }else printf("cannot reach destination
    ");
        }
        return 0;
    }
    

    spfa+二分

    $ 218MS $

    /*
    spfa+二分 
    Judge Status:Accepted
    Exe.Time:218MS		
    Exe.Memory:1740K
    Code Len:1772 B	
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    const int M=1000010;
    const int INF=0x3f3f3f3f;
    struct node{
        int h;
        int data;
    }edge[M];
    int head[N],ver[M],Next[M],d[N],v[N],ans,minn,n,m,tot,star,en,sum;
    void add(int x,int y,int z,int hi){
        ver[++tot]=y;edge[tot].data=z;edge[tot].h=hi;Next[tot]=head[x];head[x]=tot;
    }
    queue<int>q;
    void spfa(int mi){
        memset(d,0x3f,sizeof(d));
        memset(v,0,sizeof(v));
        d[star]=0;v[star]=1;
        q.push(star);
        while(q.size()){
            int x=q.front();q.pop();
            v[x]=0;
            for(int i=head[x];i;i=Next[i]){
                int y=ver[i],z=edge[i].data;
                if((d[y]>d[x]+z)&&edge[i].h>=mi){
                    d[y]=d[x]+z;
                    if(!v[y]) q.push(y),v[y]=1;
                }
            }
        }
    }
    int main(){
        while(scanf("%d %d",&n,&m)){
            if((!n)&&(!m)) return 0;
            if(sum) printf("
    ");
            memset(head,0,sizeof(head));tot=0;sum++;
            int l=0,r=0;
            for(int i=1;i<=m;++i){
                int x,y,z,h;
                scanf("%d %d %d %d",&x,&y,&h,&z);
                if(h==-1) h=INF;
                add(x,y,z,h);
                add(y,x,z,h);
            }scanf("%d %d %d",&star,&en,&r);
            ans=0;minn=0;
            while(l<=r){
                int mid=(l+r)>>1;
                spfa(mid);
                if(d[en]!=INF){
                    if(mid>ans){
                        ans=mid;
                        minn=d[en];
                    }
                    l=mid+1;
                }else r=mid-1;
            }
            printf("Case %d:
    ",sum);
            if(ans!=0){
                printf("maximum height = %d
    ",ans);
                printf("length of shortest route = %d
    ",minn);
            }else printf("cannot reach destination
    ");
        }
        return 0;
    }
    

    枚举+spfa

    $ 390MS $

    /*
    spfa+枚举 
    Judge Status:Accepted
    Exe.Time:390MS
    Exe.Memory:1768K	
    Code Len:1668 B
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    const int M=1000010;
    const int INF=0x3f3f3f3f;
    struct node{
        int h;
        int data;
    }edge[M];
    int head[N],ver[M],Next[M],d[N],v[N],ans,minn,n,m,tot,star,en,sum;
    void add(int x,int y,int z,int hi){
        ver[++tot]=y;edge[tot].data=z;edge[tot].h=hi;Next[tot]=head[x];head[x]=tot;
    }
    queue<int>q;
    void spfa(int mi){
        memset(d,0x3f,sizeof(d));
        memset(v,0,sizeof(v));
        d[star]=0;v[star]=1;
        q.push(star);
        while(q.size()){
            int x=q.front();q.pop();
            v[x]=0;
            for(int i=head[x];i;i=Next[i]){
                int y=ver[i],z=edge[i].data;
                if((d[y]>d[x]+z)&&edge[i].h>=mi){
                    d[y]=d[x]+z;
                    if(!v[y]) q.push(y),v[y]=1;
                }
            }
        }
    }
    int main(){
        while(scanf("%d %d",&n,&m)){
            if((!n)&&(!m)) return 0;
            if(sum) printf("
    ");
            memset(head,0,sizeof(head));tot=0;sum++;
            int l=0,r=0;
            for(int i=1;i<=m;++i){
                int x,y,z,h;
                scanf("%d %d %d %d",&x,&y,&h,&z);
                if(h==-1) h=INF;
                add(x,y,z,h);
                add(y,x,z,h);
            }scanf("%d %d %d",&star,&en,&r);
            ans=0;minn=0;
            for(int i=r;i;--i){
                spfa(i);
                if(d[en]!=INF){
                    ans=i;
                    minn=d[en];
                    break;
                }  
            }
            printf("Case %d:
    ",sum);
            if(ans!=0){
                printf("maximum height = %d
    ",ans);
                printf("length of shortest route = %d
    ",minn);
            }else printf("cannot reach destination
    ");
        }
        return 0;
    }
    

    dijkstra(堆优化)+枚举

    $ 405MS $

    /*
    dijkstra(堆优化)+枚举
    Judge Status:Accepted
    Exe.Time:405MS	
    Exe.Memory:1752K
    Code Len:2558 B
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    const int M=1000010;
    const int INF=0x3f3f3f3f;
    struct node{
        int h;
        int data;
    }edge[M];
    int head[N],ver[M],Next[M],ans,minf,n,m,tot,star,en,sum,addmin;
    void add(int x,int y,int z,int hi){
        ver[++tot]=y;edge[tot].data=z;edge[tot].h=hi;Next[tot]=head[x];head[x]=tot;
    }
    struct nod{
    	int data;
    	int num;
    }minn[M];
    int d[N];
    bool book[N];
    void shiftdownmin(int x){
        int t,flag=0;
        while(x*2<=addmin&&flag==0){
            if(minn[x].data>minn[x*2].data)t=x*2;
            else t=x;
            if(x*2+1<=addmin){
                if(minn[t].data>minn[x*2+1].data)t=x*2+1;
            }
            if(t!=x){
                swap(minn[t],minn[x]);
                x=t;
            }else flag=1;
        }
    }
    void shiftupmin(int x) {
        int flag=0; 
        if(x==1) return; 
        while(x!=1&&flag==0){
            if(minn[x].data<minn[x/2].data) swap(minn[x],minn[x/2]);
            else flag=1;
            x=x/2;
        }
    }
    void dijkstra(int mi){
    	memset(book,0,sizeof(book));
    	memset(d,0x3f,sizeof(d));addmin=0;
    	d[star]=0;
        minn[++addmin].data=0;
        minn[addmin].num=star;
        while(addmin){
            int x=minn[1].num;
    		minn[1]=minn[addmin--];
    		shiftdownmin(1);
            if(book[x]) continue;
            book[x]=1;
            for(int i=head[x];i;i=Next[i]){
                int y=ver[i],z=edge[i].data;
                if(d[y]>d[x]+z&&edge[i].h>=mi){
                    d[y]=d[x]+z;
                    minn[++addmin].num=y;
                    minn[addmin].data=d[y];
                    shiftupmin(addmin);
                }
            }
        }
    }
    int main(){
        while(scanf("%d %d",&n,&m)){
            if((!n)&&(!m)) return 0;
            if(sum) printf("
    ");
            memset(head,0,sizeof(head));tot=0;sum++;
            int l=0,r=0;
            for(int i=1;i<=m;++i){
                int x,y,z,h;
                scanf("%d %d %d %d",&x,&y,&h,&z);
                if(h==-1) h=INF;
                add(x,y,z,h);
                add(y,x,z,h);
            }scanf("%d %d %d",&star,&en,&r);
            ans=0;minf=0;
            for(int i=r;i;--i){
            	dijkstra(i);
            	if(d[en]!=INF){
                	ans=i;
                	minf=d[en];
                	break;
            	}
            }
            printf("Case %d:
    ",sum);
            if(ans!=0){
                printf("maximum height = %d
    ",ans);
                printf("length of shortest route = %d
    ",minf);
            }else printf("cannot reach destination
    ");
        }
        return 0;
    }
    

    dijkstra+二分

    $ 1154MS $

    /*
    dijkstra+二分 
    Judge Status:Accepted
    Exe.Time:1154MS
    Exe.Memory:9376K
    Code Len:2376 B	
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    const int M=1000010;
    const int INF=0x3f3f3f3f;
    struct node{
        int h;
        int data;
    }dis[N][N];
    int ans,minn,n,m,tot,star,en,sum;
    node d[N];
    bool book[N];
    void dijkstra(int x){
    	memset(book,0,sizeof(book));
    	memset(d,0x3f,sizeof(d));
    	for(int i=1;i<=n;++i){
    		if(dis[star][i].h>=x) d[i].data=dis[star][i].data;
    		d[i].h=dis[star][i].h;
    	} 
    	d[star].data=0;book[star]=1;
        for(int i=1;i<n;++i){
            int minx=INF;
            int op=-1;
            for(int j=1;j<=n;++j){
                if(d[j].data<minx&&book[j]!=1&&d[j].h>=x){
                    minx=d[j].data;
                    op=j;
                }
            }
            if(op!=-1){
                book[op]=1;
                for(int j=1;j<=n;++j){
                    if(d[j].data>d[op].data+dis[op][j].data&&(!book[j])&&(dis[op][j].h>=x)&&(d[op].h>=x)){
                        d[j].data=d[op].data+dis[op][j].data;
                        d[j].h=min(d[op].h,dis[op][j].h);
               		}
                }
            }
        }
    }
    int main(){
        while(scanf("%d %d",&n,&m)){
            if((!n)&&(!m)) return 0;
            if(sum) printf("
    ");
            memset(dis,0,sizeof(dis));sum++;
            for(int i=1;i<=n;++i){
            	for(int j=1;j<=n;++j){
            		if(i==j) dis[i][j].data=0;
            		else dis[i][j].data=INF;
            	}
            }
            int l=0,r=0;
            for(int i=1;i<=m;++i){
                int x,y,z,h;
                scanf("%d %d %d %d",&x,&y,&h,&z);
                if(h==-1) h=INF;
                if(h>dis[x][y].h){
                	dis[x][y].data=z;
                	dis[x][y].h=h;
                }
    			dis[y][x].data=dis[x][y].data;
                dis[y][x].h=dis[x][y].h;
            }scanf("%d %d %d",&star,&en,&r);
            ans=0;minn=0;
            while(l<=r){
            	int mid=(l+r)>>1;
            	dijkstra(mid);
                if(d[en].data!=INF){
                    if(mid>ans){
                    	ans=mid;
                    	minn=d[en].data;
                    } l=mid+1;
            	}else r=mid-1;
            }
            printf("Case %d:
    ",sum);
            if(ans!=0){
                printf("maximum height = %d
    ",ans);
                printf("length of shortest route = %d
    ",minn);
            }else printf("cannot reach destination
    ");
        }
        return 0;
    }
    

    以下是非AC代码

    /*
    dijkstra+枚举
    Judge Status:Time Limit Exceeded
    Exe.Time:10000MS
    Exe.Memory:9332K
    Code Len:2287B	
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    const int M=1000010;
    const int INF=0x3f3f3f3f;
    struct node{
        int h;
        int data;
    }dis[N][N];
    int ans,minn,n,m,tot,star,en,sum;
    node d[N];
    bool book[N];
    void dijkstra(int x){
    	memset(book,0,sizeof(book));
    	memset(d,0x3f,sizeof(d));
    	for(int i=1;i<=n;++i){
    		if(dis[star][i].h>=x) d[i].data=dis[star][i].data;
    		d[i].h=dis[star][i].h;
    	} 
    	d[star].data=0;book[star]=1;
        for(int i=1;i<n;++i){
            int minx=INF;
            int op=-1;
            for(int j=1;j<=n;++j){
                if(d[j].data<minx&&book[j]!=1&&d[j].h>=x){
                    minx=d[j].data;
                    op=j;
                }
            }
            if(op!=-1){
                book[op]=1;
                for(int j=1;j<=n;++j){
                    if(d[j].data>d[op].data+dis[op][j].data&&(!book[j])&&(dis[op][j].h>=x)&&(d[op].h>=x)){
                        d[j].data=d[op].data+dis[op][j].data;
                        d[j].h=min(d[op].h,dis[op][j].h);
               		}
                }
            }
        }
    }
    int main(){
        while(scanf("%d %d",&n,&m)){
            if((!n)&&(!m)) return 0;
            if(sum) printf("
    ");
            memset(dis,0,sizeof(dis));sum++;
            for(int i=1;i<=n;++i){
            	for(int j=1;j<=n;++j){
            		if(i==j) dis[i][j].data=0;
            		else dis[i][j].data=INF;
            	}
            }
            int l=0,r=0;
            for(int i=1;i<=m;++i){
                int x,y,z,h;
                scanf("%d %d %d %d",&x,&y,&h,&z);
                if(h==-1) h=INF;
                if(h>dis[x][y].h){
                	dis[x][y].data=z;
                	dis[x][y].h=h;
                }
    			dis[y][x].data=dis[x][y].data;
                dis[y][x].h=dis[x][y].h;
            }scanf("%d %d %d",&star,&en,&r);
            ans=0;minn=0;
            for(int i=r;i;--i){
            	dijkstra(i);
            	if(d[en].data!=INF){
                	ans=i;
                	minn=d[en].data;
                	break;
            	}
            }
            printf("Case %d:
    ",sum);
            if(ans!=0){
                printf("maximum height = %d
    ",ans);
                printf("length of shortest route = %d
    ",minn);
            }else printf("cannot reach destination
    ");
        }
        return 0;
    }
    
    /*
    floyd+枚举 
    Judge Status:Time Limit Exceeded
    Exe.Time:10000MS
    Exe.Memory:9740K
    Code Len:1819 B
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    const int M=1000010;
    const int INF=0x3f3f3f3f;
    struct node{
        int h;
        int data;
    }dis[N][N];
    int ans,minn,n,m,tot,star,en,sum;
    node d[N][N];
    queue<int>q;
    void floyd(int x){
    	memset(d,0x3f,sizeof(d));
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j){
                if(dis[i][j].h>=x) d[i][j].data=dis[i][j].data;
                d[i][j].h=dis[i][j].h;
            }
        }
         for(int k=1;k<=n;++k){
             for(int i=1;i<=n;++i){
                 for(int j=1;j<=n;++j){
                     if((d[i][j].data>d[i][k].data+d[k][j].data)&&(d[i][k].h>=x)&&(d[k][j].h>=x)){
                        d[i][j].data=d[i][k].data+d[k][j].data;
                        d[i][j].h=min(d[i][k].h,d[k][j].h);
                     }
                 }
             }
         }
    }
    int main(){
        while(scanf("%d %d",&n,&m)){
            if((!n)&&(!m)) return 0;
            if(sum) printf("
    ");
            memset(dis,0,sizeof(dis));sum++;
            for(int i=1;i<=n;++i){
                for(int j=1;j<=n;++j){
                    if(i==j) dis[i][j].data=0;
                    else dis[i][j].data=INF;
                }
            }
            int l=0,r=0;
            for(int i=1;i<=m;++i){
                int x,y,z,h;
                scanf("%d %d %d %d",&x,&y,&h,&z);
                if(h==-1) h=INF;
                if(h>dis[x][y].h){
                    dis[x][y].data=z;
                    dis[x][y].h=h;
                }
                dis[y][x].data=dis[x][y].data;
                dis[y][x].h=dis[x][y].h;
            }scanf("%d %d %d",&star,&en,&r);
            ans=0;minn=0;
            for(int i=r;i;--i){
                floyd(i);
                if(d[star][en].data!=INF){
                    ans=i;
                    minn=d[star][en].data;
                    break;
                }  
            }
            printf("Case %d:
    ",sum);
            if(ans!=0){
                printf("maximum height = %d
    ",ans);
                printf("length of shortest route = %d
    ",minn);
            }else printf("cannot reach destination
    ");
        }
        return 0;
    }
    
    /*
    /*
    floyd+二分 
    Judge Status:Time Limit Exceeded
    Exe.Time:10000MS
    Exe.Memory:12212K
    Code Len:1891 B
    */
    #include<bits/stdc++.h>
    using namespace std;
    const int N=1010;
    const int M=1000010;
    const int INF=0x3f3f3f3f;
    struct node{
        int h;
        int data;
    }dis[N][N];
    int ans,minn,n,m,tot,star,en,sum;
    node d[N][N];
    queue<int>q;
    void floyd(int x){
    	memset(d,0x3f,sizeof(d));
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=n;++j){
    			if(dis[i][j].h>=x) d[i][j].data=dis[i][j].data;
    			d[i][j].h=dis[i][j].h;
    		}
    	}
     	for(int k=1;k<=n;++k){
     		for(int i=1;i<=n;++i){
     			for(int j=1;j<=n;++j){
     				if((d[i][j].data>d[i][k].data+d[k][j].data)&&(d[i][k].h>=x)&&(d[k][j].h>=x)){
    					d[i][j].data=d[i][k].data+d[k][j].data;
    					d[i][j].h=min(d[i][k].h,d[k][j].h);
     				}
     			}
     		}
     	}
    }
    int main(){
        while(scanf("%d %d",&n,&m)){
            if((!n)&&(!m)) return 0;
            if(sum) printf("
    ");
            memset(dis,0,sizeof(dis));sum++;
            for(int i=1;i<=n;++i){
            	for(int j=1;j<=n;++j){
            		if(i==j) dis[i][j].data=0;
            		else dis[i][j].data=INF;
            	}
            }
            int l=0,r=0;
            for(int i=1;i<=m;++i){
                int x,y,z,h;
                scanf("%d %d %d %d",&x,&y,&h,&z);
                if(h==-1) h=INF;
                if(h>dis[x][y].h){
                	dis[x][y].data=z;
                	dis[x][y].h=h;
                }
    			dis[y][x].data=dis[x][y].data;
                dis[y][x].h=dis[x][y].h;
            }scanf("%d %d %d",&star,&en,&r);
            ans=0;minn=0;
            while(l<=r){
            	int mid=(l+r)>>1;
            	floyd(mid);
                if(d[star][en].data!=INF){
                    if(mid>ans){
                    	ans=mid;
                    	minn=d[star][en].data;
                    } l=mid+1;
            	}else r=mid-1;
            }
            printf("Case %d:
    ",sum);
            if(ans!=0){
                printf("maximum height = %d
    ",ans);
                printf("length of shortest route = %d
    ",minn);
            }else printf("cannot reach destination
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    Swift学习一
    Swift开发学习(一):初始篇
    objc_msgSend arm64 崩溃问题
    更改navigationController push和pop界面切换动画
    iOS 改变UITextField中光标颜色
    IOS Core Animation Advanced Techniques的学习笔记(五)
    使用CAShapeLayer与UIBezierPath画出想要的图形
    亮相SIGGRAPH 太极拳三维教学App制作揭秘
    MySQL优化——索引
    求职前一个月复习知识
  • 原文地址:https://www.cnblogs.com/donkey2603089141/p/11748150.html
Copyright © 2011-2022 走看看