小Y的旅行

【题目描述】

小Y要经过一个图,从1号点到达N号点,每个点设有休息站。小Y计划用最多K天走完全程,除第K天外,每一天小Y都必须在休息站过夜。所以,一段路必须在同一天走完。小Y的体力有限,他希望走的路程最大的一天中走的路尽可能少,请求出这个最小值。

【输入描述】

第一行三个整数N、M、K,表示图的顶点数、边数、天数。从第二行开始,之后的M行,每行三个整数Ui、Vi、Wi表示从Ui和Vi间有一条双向道路,长度为Wi。

【输出描述】

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

【输入样例】
3 2 4

3 2 4

1 2 1

【输出样例】
4
【数据范围及提示】

对于100%的数据,2 <= N <= K <= 7500,0 <= M <= 200000,1 <= Wi <= 10^9,保证没有重边和自环。

源代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Node
{
    int T,T1,T2;
}i[200001];
int m,n,k,ans=-1,F[7501];
int Find(int t)
{
    if (!F[t])
      return t;
    return F[t]=Find(F[t]);
}
bool Check(int t)
{
    for (int a=1;a<=n;a++)
      F[a]=0;
    for (int a=1;a<=m;a++)
    {
          if (i[a].T>t)
            continue;
          int t1=Find(i[a].T1);
          int t2=Find(i[a].T2);
          if (t1!=t2)
            F[t2]=t1;
          if (Find(1)==Find(n))
            return true;
    }
    return false;
}
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    int Max(0);
    for (int a=1;a<=m;a++)
    {
        int t,t1,t2;
        scanf("%d%d%d",&i[a].T1,&i[a].T2,&i[a].T);
        Max=max(Max,i[a].T);
    }
    int Left=0,Right=Max;
    while (Left<=Right)
    {
        int Mid=(Left+Right)>>1;
        if (Check(Mid))
        {
            ans=Mid;
            Right=Mid-1;
        }
        else
          Left=Mid+1;
    }
    printf("%d",ans);
    return 0;
}

/*
    思路:一维记录数据,二分答案,并查集检验。
        Question:为什么这样取边检验是对的呢?
        Answer:智障,你看到数据范围了吗?N <= K!一天至少走一条啊!水水水!
    反思教训:闪开,想当然!让我歌唱灵活思维与数据范围!
*/

 

posted @ 2016-08-20 18:01  前前前世。  阅读(187)  评论(0编辑  收藏  举报