poj3662Telephone Lines——二分+最短路

Posted Zinn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj3662Telephone Lines——二分+最短路相关的知识,希望对你有一定的参考价值。

题目:http://poj.org/problem?id=3662

二分答案找出符合条件的最小长度;

假设了每个长度后,以这个为标准对每条边赋值,0为小于等于,1为大于,然后按这个值来跑最短路,在看看能否使用不超过k根长电线;

注意不能到达要输出-1!

不知为何l从0开始就A了,从最短的电线开始就是WA,可怖的细节;

总之,0和1这个技巧很美,打破了最短路的常规思路。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
queue<int>q;
int n,p,k,head[1005],ct,l,r,dis[1005];
bool vis[1005];
struct N{
    int to,next,w,c;
    N(int t=0,int n=0,int w=0):to(t),next(n),w(w) {}
}edge[20005];
bool spfa()
{    
    memset(vis,0,sizeof vis);
    memset(dis,3,sizeof dis);
    while(q.size())q.pop();
    q.push(1);vis[1]=1;dis[1]=0;
    while(q.size())
    {
        int x=q.front();q.pop();
        vis[x]=0;
        for(int i=head[x];i;i=edge[i].next)
        {
            int u=edge[i].to;
            if(dis[u]>dis[x]+edge[i].c)
            {
                dis[u]=dis[x]+edge[i].c;
                if(!vis[u])
                {
                    vis[u]=1;
                    q.push(u);
                }
            }
        }
    }
    return dis[n]<=k;
}
bool cl(int x)
{
    for(int i=1;i<=ct;i++)
    {
        if(edge[i].w<=x)edge[i].c=0;
        else edge[i].c=1;
    }
    return spfa();
}
int main()
{
    while(scanf("%d%d%d",&n,&p,&k)==3)
    {
        ct=0;
        memset(head,0,sizeof head);
//        l=1000005;//!!
        l=0;
        r=0;
        int x,y,z;
        for(int i=1;i<=p;i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            edge[++ct]=N(y,head[x],z);head[x]=ct;
            edge[++ct]=N(x,head[y],z);head[y]=ct;
            r=max(r,z);
//            l=min(l,z);
        }
//        while(l<r)
//        {
//            int mid=(l+r)/2;
//            if(cl(mid))r=mid;
//            else l=mid+1;
//        }
        int ans=-1;//!!!
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(cl(mid))
            {
                ans=mid;
                r=mid-1;
            }
            else l=mid+1;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

以上是关于poj3662Telephone Lines——二分+最短路的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3662 Telephone Lines (分层图)

POJ 3662 Telephone Lines (分层图做法)

poj 3662 Telephone Lines(最短路+二分)

POJ3662 Telephone Lines (dijkstra+二分)

poj3662 Telephone Lines

POJ3662 Telephone Lines( dijkstral + 二分 )