BZOJ 1614: [Usaco2007 Jan]Telephone Lines

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1614

解:首先我们先用一次dijkstra来判断出特殊情况,比如说路不联通,或者说所需连的电线数小于等于提供的电线数。

然后,我们二分我们所需支付的那根最长的电线长度x,再做一遍dijkstra(当然spfa更好啦),如果过程中有访问到

比x长的电线,就给距离+1,表示这段路上需要提供多少免费连接的电线,这样最短路就是,当我们支付x元的时候,

至少要有多少免费提供的电线,如果可以提供这么多的话,就更新答案,说明我们付x元就够了。

程序:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#define maxn 2100000000
using namespace std;
struct ding{
  int to,next,val;
}edge[40000];
bool vis[40000];
int ans=maxn,head[4000],cnt,n,p,k,dis[40000],w[40000];
void add(int u,int v,int op)
{
  edge[++cnt].to=v; edge[cnt].val=op; edge[cnt].next=head[u]; head[u]=cnt;
}
void dijkstra(int x)
{
  dis[1]=0;
  for (int i=2;i<=n;i++) dis[i]=maxn;
  for (int i=1;i<=n;i++) vis[i]=false;
  for (int tot=1;tot<=n;tot++)
  {
      int minx=maxn; int ch=0;
      for (int i=1;i<=n;i++)
      if ((!vis[i])&&(dis[i]<minx))
      {
        minx=dis[i];
      ch=i;
    }
    if ((ch==0)||(ch==n)) break;
    vis[ch]=true;
    for (int i=head[ch];i;i=edge[i].next)
    {
      int y=edge[i].to;
      if (edge[i].val<=x) dis[y]=min(dis[y],dis[ch]);
      else dis[y]=min(dis[y],dis[ch]+1);
    }
  }
}
int check(int x)
{
  dijkstra(x);
  if (dis[n]<=k) return true;
  else return false;
}
void dijkstra1()
{
  for (int i=2;i<=n;i++) dis[i]=maxn;
  dis[1]=0;
  for (int tot=1;tot<=n;tot++)
  {
      int minx=maxn; int ch=0;
      for (int i=1;i<=n;i++)
      if ((!vis[i])&&(dis[i]<minx))
      {
        minx=dis[i];
      ch=i;
    }
    if ((ch==0)||(ch==n)) break;
    vis[ch]=true;
    for (int i=head[ch];i;i=edge[i].next)
    {
      int y=edge[i].to;
      if (!vis[y]) dis[y]=min(dis[y],dis[ch]+1);
    }
  }
}
int main()
{
  scanf("%d%d%d",&n,&p,&k);
  int a,b;
  for (int i=1;i<=p;i++)
  {
    scanf("%d%d%d",&a,&b,&w[i]);
    add(a,b,w[i]); add(b,a,w[i]);
  }
  dijkstra1();
  if (dis[n]<=k) {printf("0\n");return 0;}
  else if (dis[n]==maxn) {printf("-1\n");return 0;}
  sort(w+1,w+1+p);
  int l=1,r=p;
  while (l<=r)
  {
      int mid=(l+r)/2;
      if (check(w[mid]))
      {
        ans=min(ans,w[mid]);
      r=mid-1;
    }
    else l=mid+1;
  }
  printf("%d\n",ans);
  return 0;
}
时间: 2024-08-09 21:30:25

BZOJ 1614: [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顺次编号的废

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架设电话线*

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

【二分答案】【最短路】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

[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

[Usaco2007 Jan]Telephone Lines架设电话线

好题!...(躺) 一开始推个分层图最短路...然后发现并不是求最短路(躺 这题题目大意我没看错应该是这样的: 找一条1~n的路径,使路径上第k+1大的数尽可能的小 这个提法是不是有点眼熟... 假设有这样一个问题: 找一条1~n的路径,使路径上最大的数最小 “使最大的最小”,二分答案! 然后我就不会了 hzwer有一个很妙的思路orz... 大概是这个意思吧... 二分一下路径上最大的边权mx,然后对最短路变一下形 把>mx的边权当做1,<=mx的边权当做0,因为>mx的肯定要用一次减

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).数

[BZOJ] 1636: [Usaco2007 Jan]Balanced Lineup

1636: [Usaco2007 Jan]Balanced Lineup Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 909  Solved: 644[Submit][Status][Discuss] Description For the daily milking, Farmer John's N cows (1 <= N <= 50,000) always line up in the same order. One day Farmer