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;
}

原文地址:https://www.cnblogs.com/Zinn/p/8698385.html

时间: 2024-10-11 16:06:52

poj3662Telephone Lines——二分+最短路的相关文章

POJ3662Telephone Lines(最短路+二分)

传送门 题目大意:n个点p条边,每条边有权值,让1和n点联通,可以将联通1--n的边选k条免费, 求剩下边权的最大值. 题解:二分一个答案x,大于x的边权设为1,小于等于x的边权设为0,跑最短路. 若从1到n的最短路dis[n]<=k,则可以通过免费k条边,答案为x. 代码: #include<iostream> #include<cstdio> #include<queue> #include<cstring> #include<algorit

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

查看题目 最小化第K大值. 让我怀疑人生的一题目,我有这么笨? 1 #include <cstdio> 2 #include <queue> 3 #include <cstring> 4 #include <vector> 5 #include <functional> 6 using namespace std; 7 #define maxv 1010 8 #define maxl 1000000 9 struct edge 10 { 11 i

【HDU 1839】 Delay Constrained Maximum Capacity Path(二分+最短路)

[HDU 1839] Delay Constrained Maximum Capacity Path(二分+最短路) Delay Constrained Maximum Capacity Path Time Limit: 10000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 1515    Accepted Submission(s): 481 Problem

hdu 2962 Trucking (二分+最短路Spfa)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2962 Trucking Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1763    Accepted Submission(s): 618 Problem Description A certain local trucking co

HDU 1839 Delay Constrained Maximum Capacity Path(二分+最短路)

题目地址:HDU 1839 我去..原来这题这么简单...网络流中这种二分建图的方式做了一大堆了..这种题还能难倒我吗...白天一直没怎么看懂题,对题意懵懵懂懂的...晚上好好看了看题,这不就是网络流中练的最多的那种二分建图模型吗....只是把网络流算法改成最短路就行了..但是两个地方手残了没能在实验室当场A掉..sad... 这题就是二分最小容量,对满足容量的加边,对时间求最短路.如果最短时间比规定时间少的话就可以继续增加容量,直到不能增加为止. 代码如下: #include <iostrea

二分+最短路

二分+最短路 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu POJ 3662 Description 多年以后,笨笨长大了,成为了电话线布置师.由于地震使得某市的电话线全部损坏,笨笨是负责接到震中市的负责人.该市周围分布着N(1<=N<=1000)根据1……n顺序编号的废弃的电话线杆,任意两根线杆之间没有电话线连接,一共有p(1<=p<=10000)对电话杆可以拉电话线.

POJ 2391Ombrophobic Bovines(二分+最短路+网络流之最大流)

题目地址:http://poj.org/problem?id=2391 这个题WA了一晚上,原因是数组开小了,然后又TLE了一天,原因是数组改的过大了....不多说什么了... 思路不难,建图也不难,二分时间,然后把每个田地之间的最短距离用floyd最短路求出来.然后建立一个源点与汇点,将田地拆分成两个点,在距离之内的进行连边,要单向连边.然后将源点与田地相连,权值为每个田地的牛的数目,再把另一边的田地与汇点相连,权值为每个田地最大可避雨的牛的数目.拆开的田地之间权值可以为无穷大. 代码如下:

P1462 通往奥格瑞玛的道路 (二分+最短路)

题目 P1462 通往奥格瑞玛的道路 给定\(n\)个点\(m\)条边,每个点上都有点权\(f[i]\),每条边上有边权,找一条道路,使边权和小于给定的数\(b\),并使最大点权最小. 解析 二分一下钱,然后跑最短路,判断一下如果只有这么多钱的话能不能到终点(最短路边权和是不是不超过\(b\)),套个最短路板子,套个二分板子,没了. 代码 //二分+最短路 #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10;

poj3662 Telephone Lines【最短路】【二分】

http://poj.org/problem?id=3662 Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions:9310   Accepted: 3374 Description Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative,