UVALive - 4223

题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2224

题意:有n个城市,m条路,每条路是双向的,从一个城市到另一个城市,并且有限制通行高度,有路程。

现在有一辆货车,有一个最高货物高度,要从一个城市到一个城市。要保证最高高度情况下,选最短路。

思路:我们可以知道最高高度一定是1到货车高度。所以我们可以二分高度,寻找最高高度,再有dijkstra求最短路。

但是用邻接矩阵会超时,这里可以稍稍剪枝下。怎么剪呢?只要在dijkstra算法里判断达到所求终点,或者没有路走了就退出,不用在多算。

还有一个坑点是输出格式:第一个样例不空行输出答案,而后面要空行再输出答案。而且格式错了居然是 WA!!!

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
struct node{
    int v,h;
}map[1050][1050];
int n,m,high,maxh,from,to,ansh,ansv,flag;
int dis[1050],vis[1050];

void dijktra(int x)
{
    memset(vis,0,sizeof(vis));
    vis[from]=1;
    for(int i=1;i<=n;i++)//不达到高度x的路相当于不通,赋inf即可 
    { 
        if(map[from][i].h>=x)
            dis[i]=map[from][i].v;
        else
            dis[i]=inf;    
    } 
    for(int i=1;i<n;i++)//dijkstra模板 
    {
        int t=inf,p=-1;
        for(int j=1;j<=n;j++)
        { 
            
            if(!vis[j]&&dis[j]<t)
            {
                t=dis[j];
                p=j;
            }
        } 
        vis[p]=1;
        if(p==to||p==-1)//剪枝 
            return ; 
        for(int j=1;j<=n;j++)
        {
            if(!vis[j]&&dis[j]>map[p][j].v+dis[p]&&map[p][j].h>=x)
                dis[j]=map[p][j].v+dis[p];
        }
    }
}
void solve()//二分求高度 
{
    int l=1,r=high;
    while(l<=r)
    {
        int mid=(l+r)/2;
        dijktra(mid);
        if(dis[to]!=inf)//mid高度有最短路 
        {
            flag=1;
            ansh=mid;
            ansv=dis[to];
            l=mid+1;
        }
        else
            r=mid-1;
    }
    return ;
}
int main()
{
    int k=1;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        flag=0;
        for(int i=1;i<=n;i++)//初始化 
        {
            for(int j=1;j<=n;j++)
            {
                map[i][j].h=0;
                map[i][j].v=inf;
            }
        }
        if(!n&&!m)
            break;
        int u,v,g,w;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d%d",&u,&v,&g,&w);
            if(g==-1)    g=inf;//-1为不限高度 
            map[u][v].v=map[v][u].v=w;
            map[u][v].h=map[v][u].h=g;
        }
        scanf("%d%d%d",&from,&to,&high);
        solve();
        if(k>1)
            printf("\n");
        printf("Case %d:\n",k++);
        if(flag)
        {
            printf("maximum height = %d\n",ansh);
            printf("length of shortest route = %d\n",ansv);
        }
        else
            printf("cannot reach destination\n");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xiongtao/p/9441572.html