二分+最短路

二分+最短路

Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

POJ 3662

Description

多年以后,笨笨长大了,成为了电话线布置师。由于地震使得某市的电话线全部损坏,笨笨是负责接到震中市的负责人。该市周围分布着N(1<=N<=1000)根据1……n顺序编号的废弃的电话线杆,任意两根线杆之间没有电话线连接,一共有p(1<=p<=10000)对电话杆可以拉电话线。其他的由于地震使得无法连接。

第i对电线杆的两个端点分别是ai,bi,它们的距离为li(1<=li<=1000000)。数据中每对(ai,bi)只出现一次。编号为1的电话杆已经接入了全国的电话网络,整个市的电话线全都连到了编号N的电话线杆上。也就是说,笨笨的任务仅仅是找一条将1号和N号电线杆连起来的路径,其余的电话杆并不一定要连入电话网络。

电信公司决定支援灾区免费为此市连接k对由笨笨指定的电话线杆,对于此外的那些电话线,需要为它们付费,总费用决定于其中最长的电话线的长度(每根电话线仅连接一对电话线杆)。如果需要连接的电话线杆不超过k对,那么支出为0.

请你计算一下,将电话线引导震中市最少需要在电话线上花多少钱?

Input

输入文件的第一行包含三个数字n,p,k;

第二行到第p+1行,每行分别都为三个整数ai,bi,li。

Output

一个整数,表示该项工程的最小支出,如果不可能完成则输出-1.

Sample Input

5 7 1
1 2 5
3 1 4
2 4 8
3 2 3
5 2 9
3 4 7
4 5 6

Sample Output

4

//挺有意思的一道题,要使第 k+1 边的值越小越好。想不到啊,spfa还能这么用,二分还能这么用

79ms

 1 #include <stdio.h>
 2 #include <string.h>
 3
 4 #define MAXN 1005
 5
 6 struct Edge{
 7     int v,w;
 8     int next;
 9 }edge[30005];
10 int headlist[MAXN];
11
12 int n,p,k,bian=0;
13
14 void join(int a,int b,int c)
15 {
16     bian++;
17     edge[bian].v=b;
18     edge[bian].w=c;
19     edge[bian].next=headlist[a];
20     headlist[a]=bian;
21 }
22
23 int Q[1000];
24 int vis[MAXN];
25 int dis[MAXN];//大于limit的最少有多少个
26 int spfa(int limit)
27 {
28     for (int i=1;i<=n;i++)
29         dis[i]=10000000;//kanknkkkkkkkkkkkkk
30     memset(vis,0,sizeof(vis));
31
32     Q[0]=1;
33     int l=0,r=1;
34     dis[1]=0,vis[1]=1;
35     while (l!=r)
36     {
37         int now=Q[l++];
38         if (l==1000) l=0;
39         vis[now]=0;
40         int i=headlist[now];
41         int mm=dis[now];
42         while (i)
43         {
44             if (edge[i].w>limit) mm=dis[now]+1;
45             else mm=dis[now];
46             if (mm<dis[edge[i].v])
47             {
48                 dis[edge[i].v]=mm;
49                 if (vis[edge[i].v]==0)
50                 {
51                     Q[r++]=edge[i].v;
52                     if (r==1000) r=0;
53                     vis[edge[i].v]=1;
54                 }
55             }
56             i=edge[i].next;
57         }
58     }
59     if (dis[n]<=k) return 1;//
60     return 0;
61 }
62
63 int main()
64 {
65     scanf("%d%d%d",&n,&p,&k);
66     int a,b,c;
67     for (int i=1;i<=p;i++)
68     {
69         scanf("%d%d%d",&a,&b,&c);
70         join(a,b,c);
71         join(b,a,c);
72     }
73     int l=0,r=1000000,ans=-1;
74     while (l<=r)
75     {
76         int mid=(l+r)/2;
77         if (spfa(mid))
78         {
79             ans=mid;//记录后,看能不能有更小的值符合条件
80             r=mid-1;
81         }
82         else l=mid+1;//不能的话,只能看有没更大的了
83     }
84     printf("%d\n",ans);
85     return 0;
86 }

时间: 2024-12-26 16:03:18

二分+最短路的相关文章

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

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

【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

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

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

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

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

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

二分+最短路判定 BZOJ 2709: [Violet 1]迷宫花园

BZOJ 2709: [Violet 1]迷宫花园 Sample Input 5 10.28 9 9 ######### # # # # # # # #S# # ##### # # ## # # # ### ### ##E # ######### 4.67 9 9 ######### # ## ## ### #S# # # # E ## # # ##### # ## ### # ##### # # # # ######### 39.06 9 9 ######### # # # # # # # #

hdu2363Cycling 二分+最短路

//一个无向图 ,每个点都有高度, //问从起点1到终点n的最高点减最低点的差值最小的前提下的最短路和这个差值 //由于n<100所以可以先将这n个点按升序排,枚举这个最短路的左边最小mi,二分找最小的右边ma #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std ; const int maxn = 110 ; con

hdu2962Trucking 二分+最短路

//一个无向图,每一条路有限制载重和长度 //问从起点到终点的最大载重,以及在最大载重的情况下的最短路是多少 //二分最大栽重,对于每个载重,小于这个载重的路径不走 #include<iostream> #include<cstring> #include<cstdio> using namespace std ; const int maxn = 1010 ; const int inf = 0x3f3f3f3f ; int vis[maxn] , dis[maxn]

poj3662Telephone Lines——二分+最短路

题目:http://poj.org/problem?id=3662 二分答案找出符合条件的最小长度: 假设了每个长度后,以这个为标准对每条边赋值,0为小于等于,1为大于,然后按这个值来跑最短路,在看看能否使用不超过k根长电线: 注意不能到达要输出-1! 不知为何l从0开始就A了,从最短的电线开始就是WA,可怖的细节: 总之,0和1这个技巧很美,打破了最短路的常规思路. 代码如下: #include<iostream> #include<cstdio> #include<cst