Trucking HDU - 2962

点击打开链接

题目要求找到最大的可到达目的地的货运量 此处需要用到二分

当前高度下 可以到达目的地 下次循环就把高度上调 找不到就下调

还有就是在求最短路时要处理好某条边高度限制的问题

 

可不知道哪里边界处理有问题 不断WA..

搞了两三个小时 从网上找了个和自己思路几乎一模一样的博客借鉴一下 实属无奈

#include <stdio.h>
#include <algorithm>
#include <queue>
#define N 999999999
using namespace std;

struct node1
{
    int len;
    int lim;
};

struct node2
{
    friend bool operator < (node2 n1,node2 n2)
    {
        return n1.len>n2.len;
    }
    int id;
    int len;
};

struct node1 e[1001][1001];
int dis[1001],book[1001];
int n,m,height,s,f,pre;

int calculate(int h);

int main()
{
    int i,j,a,b,c,d,l,m,r,ans,num;
    num=1;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0) break;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(i==j)
                {
                    e[i][j].len=0;
                    e[i][j].lim=N;
                }
                else
                {
                    e[i][j].len=N;
                    e[i][j].lim=0;
                }
            }
        }
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            if(c==-1) c=N;
            e[a][b].len=d;
            e[a][b].lim=c;
            e[b][a].len=d;
            e[b][a].lim=c;
        }
        scanf("%d%d%d",&s,&f,&height);
        l=1,r=height;
        while(l<=r)
        {
            m=(l+r)/2;
            if(calculate(m))
            {
                ans=dis[f];
                l=m+1;
            }
            else
            {
                r=m-1;
            }
        }
        if(num!=1) printf("\n");
        printf("Case %d:\n",num++);
        if(r==0) printf("cannot reach destination\n");//
        else
        {
            printf("maximum height = %d\n",r);
            printf("length of shortest route = %d\n",ans);
        }
    }
    return 0;
}

int calculate(int h)
{
    int i,j,cnt,minn,p;
    for(i=1;i<=n;i++)
    {
        book[i]=0;
        if(e[s][i].lim>=h)
        {
            dis[i]=e[s][i].len;
        }
        else
        {
            dis[i]=N;
        }
    }
    dis[s]=0;
    book[s]=1;
    cnt=1;
    while(cnt<n)
    {
        minn=N,p=0;
        for(i=1;i<=n;i++)
        {
            if(book[i]==0&&minn>dis[i])
            {
                minn=dis[i];
                p=i;
            }
        }
        if(p==f) return 1;
        if(p!=0)
        {
            book[p]=1;
            cnt++;
            for(i=1;i<=n;i++)
            {
                if(dis[i]>dis[p]+e[p][i].len&&e[p][i].lim>=h&&book[i]==0)
                {
                    dis[i]=dis[p]+e[p][i].len;
                }
            }
        }
        else return 0;
    }
}

 

 

这是我自己WA的代码 还望高人看到指点

#include <stdio.h>
#include <algorithm>
#include <queue>
#define N 999999999
using namespace std;

struct node1
{
    int len;
    int lim;
};

struct node2
{
    friend bool operator < (node2 n1,node2 n2)
    {
        return n1.len>n2.len;
    }
    int id;
    int len;
};

struct node1 e[1001][1001];
int dis[1001],book[1001];
int n,m,height,s,f,pre,cnt,ans;

void binsearch();
int calculate(int h);

int main()
{
    int i,j,a,b,c,d,minn;
    cnt=1;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        if(n==0&&m==0) break;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(i==j)
                {
                    e[i][j].len=0;
                    e[i][j].lim=N;
                }
                else
                {
                    e[i][j].len=N;
                    e[i][j].lim=0;
                }
            }
        }
        pre=N;
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            if(c==-1) c=N*2;
            if(pre>c) pre=c;
            e[a][b].len=d;
            e[a][b].lim=c;
            e[b][a].len=d;
            e[b][a].lim=c;
        }
        scanf("%d%d%d",&s,&f,&height);
        binsearch();
    }
    return 0;
}

void binsearch()
{
    int l,m,r;
    l=1,r=height;
    while(l<=r)
    {
        m=(l+r)/2;
        ans=calculate(m);
        if(ans!=N)
        {
            l=m+1;
        }
        else
        {
            r=m-1;
        }
    }
    printf("Case %d:\n",cnt++);
    if(ans==N)
    {
        printf("cannot reach destination\n");
    }
    else
    {
        printf("maximum height = %d\n",m);
        printf("length of shortest route = %d\n",ans);
    }
    printf("\n");
    return;
}

int calculate(int h)
{
    priority_queue <struct node2> que;
    struct node2 cur,t;
    int i,j,minn,p;
    for(i=1;i<=n;i++)
    {
        if(e[s][i].lim>=h||i==s)
        {
            dis[i]=e[s][i].len;
        }
        else
        {
            dis[i]=N;
        }
        book[i]=0;
    }
    t.id=s;
    t.len=0;
    que.push(t);
    for(i=1;i<=n;i++)
    {
        if(e[s][i].lim>=h&&i!=s)
        {
            t.id=i;
            t.len=e[s][i].len;
            que.push(t);
        }
    }
    while(!que.empty())
    {
        cur=que.top();
        que.pop();
        p=cur.id;
        book[p]=1;
        for(i=1;i<=n;i++)
        {
            if(book[i]==0&&(e[p][i].lim>=h)&&dis[i]>dis[p]+e[p][i].len)
            {
                dis[i]=dis[p]+e[p][i].len;
                t.id=i;
                t.len=dis[i];
                que.push(t);
            }
        }
    }
    return dis[f];
}

 


 

这道题用到了二分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值