• BZOJ 1614 [Usaco2007 Jan]Telephone Lines架设电话线:spfa + 二分【路径中最大边长最小】


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

    题意:

      给你一个无向图,n个点,m条边。

      你需要找出一条从1到n的路径,使得这条路径上去掉k条最大的边后,剩余边中最大的边最小。

      问你最大边最小为多少。

    题解:

      求最大值最小:二分。

      二分:最大边的值L。

      check函数:

        每次一遍spfa。

        对于每条边,如果len > L,则认为该边边权为1;如果len <= L,则边权为0。

        dis[i]也就代表:从1到i最少要去掉多少条边,才能使答案为L。

        所以答案为:令dis[n] <= k的最小的L。

    AC Code:

      1 #include <iostream>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <vector>
      5 #include <queue>
      6 #define MAX_N 1005
      7 #define INF 10000000
      8 
      9 using namespace std;
     10 
     11 struct Edge
     12 {
     13     int dest;
     14     int len;
     15     Edge(int _dest,int _len)
     16     {
     17         dest=_dest;
     18         len=_len;
     19     }
     20     Edge(){}
     21 };
     22 
     23 int n,m,k;
     24 int ans=-1;
     25 int dis[MAX_N];
     26 bool vis[MAX_N];
     27 vector<Edge> edge[MAX_N];
     28 queue<int> q;
     29 
     30 void read()
     31 {
     32     cin>>n>>m>>k;
     33     int a,b,v;
     34     for(int i=0;i<m;i++)
     35     {
     36         cin>>a>>b>>v;
     37         edge[a].push_back(Edge(b,v));
     38         edge[b].push_back(Edge(a,v));
     39     }
     40 }
     41 
     42 int get_front()
     43 {
     44     int now=q.front();
     45     q.pop();
     46     vis[now]=false;
     47     return now;
     48 }
     49 
     50 void insert(int now)
     51 {
     52     if(vis[now]) return;
     53     q.push(now);
     54     vis[now]=true;
     55 }
     56 
     57 void spfa(int start,int maxl)
     58 {
     59     memset(dis,-1,sizeof(dis));
     60     memset(vis,false,sizeof(vis));
     61     insert(start);
     62     dis[start]=0;
     63     while(!q.empty())
     64     {
     65         int now=get_front();
     66         for(int i=0;i<edge[now].size();i++)
     67         {
     68             Edge temp=edge[now][i];
     69             if(dis[temp.dest]==-1 || dis[temp.dest]>dis[now]+(temp.len>maxl))
     70             {
     71                 dis[temp.dest]=dis[now]+(temp.len>maxl);
     72                 insert(temp.dest);
     73             }
     74         }
     75     }
     76 }
     77 
     78 void solve()
     79 {
     80     int lef=0;
     81     int rig=INF;
     82     while(rig-lef>1)
     83     {
     84         int mid=(lef+rig)/2;
     85         spfa(1,mid);
     86         if(dis[n]==-1) return;
     87         if(dis[n]>k) lef=mid;
     88         else rig=mid;
     89     }
     90     spfa(1,lef);
     91     if(dis[n]<=k) ans=lef;
     92     else ans=rig;
     93 }
     94 
     95 void print()
     96 {
     97     cout<<ans<<endl;
     98 }
     99 
    100 int main()
    101 {
    102     read();
    103     solve();
    104     print();
    105 }
  • 相关阅读:
    Windows API—CreateEvent—创建事件
    C++的注册和回调
    Python内置模块-logging
    使用 C++ 处理 JSON 数据交换格式
    Python生成器
    5.Spring-Boot缓存数据之Redis
    6.Spring-Boot项目发布到独立的tomcat中
    7.Spring-Boot自定义Banner
    8.Spring-Boot之SpringJdbcTemplate整合Freemarker
    9.Spring-Boot之Mybatis-LogBack-Freemarker
  • 原文地址:https://www.cnblogs.com/Leohh/p/7608511.html
Copyright © 2020-2023  润新知