「LYOI2016 Summer」Graph 题解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「LYOI2016 Summer」Graph 题解相关的知识,希望对你有一定的参考价值。

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:https://ly.men.ci/problem/44

题目描述

小 Y 又开始了一段旅途。

这次,他要经过一个图,从 1 号点到达 n 号点,每个点设有休息站。图中没有重边和自环

小 Y 计划用最多 k 天走完全程,除第 k 天外,每一天小 Y 都必须在休息站过夜。所以,一段路必须在同一天走完。

小 Y 的体力有限,他希望走的路程最大的一天中走的路尽可能少,请求出这个最小值。

输入格式

第一行三个整数 nmk表示图的顶点数、边数、天数。
从第二行开始,之后的 m行,每行三个整数 uii??、vi v_i v?i??、wi w_i w?i?? 表示从 ui u_i u?i?? 和 vi v_i v?i?? 间有一条双向道路,长度为 wi w_i w?i??。

输出格式

一行一个正整数,如果小 Y 能走完全程,输出走的路程最大的一天中走的路程最小值,否则输出 −1

样例

输入样例

3 2 4
3 2 4
1 2 1

输出样例

4

分析:

其实是个最小生成树+DFS...我还一本正经地写了SPFA...今天怕不是智障QAQ

数据保证k>=n,所以一次只需要跳一条边即可。

找出最小生成树,然后求出最小生成树上1~n的边中边权的最大值。

用神奇的DFS可以找出最大值。%%%wzy dalao

 

AC代码:

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<queue>
  6 
  7 const int MAXN = 200003;
  8 inline void read(int &x)
  9 {
 10     char ch = getchar(),c = ch;x = 0;
 11     while(ch < 0 || ch > 9) c = ch,ch = getchar();
 12     while(ch <= 9 && ch >= 0) x = (x<<1)+(x<<3)+ch-0,ch = getchar();
 13     if(c == -) x = -x;
 14 }
 15 
 16 int n,m,k,f,t,v,cnt,cc,flag;
 17 int fa[MAXN],vis[MAXN];
 18 long long ans,dis[MAXN],head[MAXN<<1];
 19 
 20 struct Edge
 21 {
 22     long long f,t,v,nxt;
 23 }e[MAXN],New[MAXN<<1];
 24 
 25 void build(long long f,long long t,long long v)
 26 {
 27     New[++cnt].f = f;
 28     New[cnt].t = t;
 29     New[cnt].v = v;
 30     New[cnt].nxt = head[f];
 31     head[f] = cnt;
 32 }
 33 
 34 int cmp(Edge a,Edge b)
 35 {
 36     return a.v < b.v; 
 37 }
 38 
 39 int find(int x)
 40 {return (fa[x] == x?x:fa[x] = find(fa[x]));}
 41 
 42 bool merge(int x,int y)
 43 {
 44     x = find(x),y = find(y);
 45     if(x != y)
 46     {
 47         fa[x] = y;
 48         return true;
 49     }
 50     return false;
 51 }
 52 
 53 inline long long Max(long long a,long long b)
 54 {return a>b?a:b;}
 55 
 56 bool dfs(int u)
 57 {
 58     vis[u] = 1;
 59     for(register int i = head[u];i;i = New[i].nxt)
 60     {
 61         long long V = New[i].t;
 62         
 63         if(V == n){
 64             ans = Max(ans,New[i].v);
 65             return 1;
 66         }
 67         if(vis[V]) continue;
 68         if(dfs(V)){
 69             ans = Max(ans,New[i].v);
 70             return 1;
 71         }
 72     }
 73     return 0;
 74 }
 75 
 76 int main()
 77 {
 78 //    freopen("1.in","r",stdin);
 79     read(n),read(m),read(k);
 80     for(register int i = 1;i <= m;++ i)
 81     {
 82         read(f),read(t),read(v);
 83         e[++cnt].f = 1LL*f;
 84         e[cnt].t = 1LL*t;
 85         e[cnt].v = 1LL*v;
 86     }
 87     for(register int i=1;i<=n;++i) fa[i] = i;
 88     std::sort(e+1,e+1+m,cmp);
 89     for(register int i = 1;i <= m;++ i)
 90     {
 91         if(merge(e[i].f,e[i].t)){
 92             build(e[i].f,e[i].t,e[i].v);
 93             build(e[i].t,e[i].f,e[i].v);
 94             printf("%d\n",e[i].v);
 95         }
 96     }
 97     dfs(1);
 98     if(!ans) printf("-1\n");
 99     else printf("%lld\n",ans);
100     return 0;
101 }

 

以上是关于「LYOI2016 Summer」Graph 题解的主要内容,如果未能解决你的问题,请参考以下文章

「LYOI2016 Summer」Digits 题解

LYOI2016 Summer 一次函数 (线段树)

「ZJU Summer Training 2020 - Round 2/3」部分补题记录

「ZJU Summer Training 2020 - Round 2/3」部分补题记录

[OI - 模拟考] LYOI2018模拟考N

SDKD 2017 Summer Single Training #03