[Usaco2007 Jan]Telephone Lines架设电话线

好题!...(躺)

一开始推个分层图最短路...然后发现并不是求最短路(躺

这题题目大意我没看错应该是这样的:

   找一条1~n的路径,使路径上第k+1大的数尽可能的小

这个提法是不是有点眼熟...

   假设有这样一个问题: 

      找一条1~n的路径,使路径上最大的数最小

   “使最大的最小”,二分答案!

然后我就不会了

hzwer有一个很妙的思路orz...

大概是这个意思吧...

  二分一下路径上最大的边权mx,然后对最短路变一下形

    把>mx的边权当做1,<=mx的边权当做0,因为>mx的肯定要用一次减免不然就超出当前的答案了

      二分答案不就是假设当前是最优的答案来确定更优的答案的区间在哪...

    然后check()就是判断dis[n]<=k?0:1

 1 #include<cstdio>
 2 #include<cstring>
 3 #define inf 0x7fffffff
 4 struct poi{int to,nxt,V;}e[20005];
 5 int cnt,head[1005];
 6 inline void add(int u,int v,int V){
 7     e[++cnt]=(poi){v,head[u],V};
 8     head[u]=cnt;
 9 }
10 int dis[1005],q[10005];
11 bool vis[1005];
12 int n,m,k,ans;
13 inline int max(int a,int b){return a>b?a:b;}
14 inline int min(int a,int b){return a<b?a:b;}
15 void spfa(int u,int mx) {
16     for(int i=1;i<=n;i++) dis[i]=inf;
17     dis[1]=0; q[0]=u; vis[u]=1;
18     int t=0,w=1;
19     while(t!=w) {
20         int now=q[t++];
21         for(int i=head[now];i;i=e[i].nxt) {
22             int to=e[i].to;
23             if((dis[now]+((e[i].V>mx)?1:0))<dis[to]) {
24                 dis[to]=dis[now]+((e[i].V>mx)?1:0);
25                 if(!vis[to]) {
26                     vis[to]=1; q[w++]=to;
27                 }
28             }
29         }
30         vis[now]=0;
31     }
32 }
33 inline bool check(int mx) {
34     spfa(1,mx);
35     return dis[n]<=k;
36 }
37 int main() {
38     scanf("%d%d%d",&n,&m,&k);
39     int l=0,r=0;
40     for(int i=1;i<=m;i++) {
41         int u,v,V;
42         scanf("%d%d%d",&u,&v,&V);
43         if(u==v) continue;
44         add(u,v,V); add(v,u,V);
45         r=max(r,V);
46     }
47     ans=-1;
48     while(l<=r) {
49         int mid=(l+r) >> 1;
50         if(check(mid)){ans=mid;r=mid-1;}
51         else l=mid+1;
52     }
53     printf("%d\n",ans);
54 }

原文地址:https://www.cnblogs.com/ZincSabian/p/9367749.html

时间: 2024-11-05 18:45:09

[Usaco2007 Jan]Telephone Lines架设电话线的相关文章

[BZOJ] 1614: [Usaco2007 Jan]Telephone Lines架设电话线

1614: [Usaco2007 Jan]Telephone Lines架设电话线 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1806  Solved: 773[Submit][Status][Discuss] Description Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用. FJ的农场周围分布着N(1 <= N <= 1,000)根按1..N顺次编号的废

bzoj1614[Usaco2007 Jan]Telephone Lines架设电话线*

bzoj1614[Usaco2007 Jan]Telephone Lines架设电话线 题意: n个节点,1号节点已经连入互联网,现在需要将整个图连入网络.有K条边可以免费连接,最后总费用为所有连边费用的最大值,求最小总费用.n≤10000 题解: 二分费用,将连边费用大于二分值的长度记为1,否则记为0,求最短路,如果到某个点的距离超过k,则需要增加答案,继续二分. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include &l

【bzoj1614】[Usaco2007 Jan]Telephone Lines架设电话线

题目描述 Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用. FJ的农场周围分布着N(1 <= N <= 1,000)根按1..N顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相连.一共P(1 <= P <= 10,000)对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接. 第i对电话线杆的两个端点分别为A_i.B_i,它们间的距离为L_i (1 <= L_i <= 1

[Usaco2007 Jan]Telephone Lines架设电话线[二分答案+最短路思想]

Description Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用. FJ的农场周围分布着N(1 <= N <= 1,000)根按1..N顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相连.一共P(1 <= P <= 10,000)对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接. 第i对电话线杆的两个端点分别为A_i.B_i,它们间的距离为 L_i (1 <= L_i

bzoj1614: [Usaco2007 Jan]Telephone Lines架设电话线(二分答案 + spfa)

原题链接 题目描述:FarmerJohn打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用.FJ的农场周围分布着N(1<=N<=1,000)根按1..N顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相连.一共P(1<=P<=10,000)对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接.第i对电话线杆的两个端点分别为A_i.B_i,它们间的距离为L_i(1<=L_i<=1,000,000).数

1614: [Usaco2007 Jan]Telephone Lines架设电话线

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1614 做法:二分答案 首先附上让我找了两天错的代码 #include<queue> #include<iostream> #include<cstdio> #include<cstring> using namespace std; struct data{int to,next,c;}e[20001]; int n,p,k,cnt,head[1001

【二分答案】【最短路】bzoj1614 [Usaco2007 Jan]Telephone Lines架设电话线

对于二分出的答案x而言,验证答案等价于将所有边权>x的边赋成1,否则赋成0,然后判断从1到n的最短路是否<=K. #include<cstdio> #include<cstring> #include<queue> using namespace std; #define N 1001 #define M 10001 int n,m,K,Xs[M],Ys[M],Zs[M]; int first[N],next[M<<1],v[M<<1

【SPFA+二分答案】BZOJ1614- [Usaco2007 Jan]Telephone Lines架设电话线

沉迷于刷水 以前的那个二分写法过不了QAQ 换了一种好像大家都比较常用的二分.原因还不是很清楚. [题目大意] 给出一张图,可以将其中k条边的边权减为0,求1到n的路径中最长边的最小值. [思路] 二分答案,即最长边的最小值x.对于每次check(x),我们将边权大于x的边设为1,边权小于等于x的边设为0,跑SPFA,结果相当于最少经过多少条边权大于x的边.如果SPFA结果>k,则不可行,否则可行. 1 #include<iostream> 2 #include<cstdio>

bzoj 1705;poj 3612:[Usaco2007 Nov]Telephone Wire 架设电话线

Description 最近,Farmer John的奶牛们越来越不满于牛棚里一塌糊涂的电话服务 于是,她们要求FJ把那些老旧的电话线换成性能更好的新电话线. 新的电话线架设在已有的N(2 <= N <= 100,000)根电话线杆上, 第i根电话线杆的高度为height_i米(1 <= height_i <= 100). 电话线总是从一根电话线杆的顶端被引到相邻的那根的顶端 如果这两根电话线杆的高度不同,那么FJ就必须为此支付 C*电话线杆高度差(1 <= C <=