【题目描述】
小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!一天至少走一条啊!水水水! 反思教训:闪开,想当然!让我歌唱灵活思维与数据范围! */