Graph
( graph .cpp/c/pas)
Description
小 Y 又开始了一段旅途。
这次,他要经过一个图,从1号点到达n号点,每个点设有休息站。
小 Y 计划用最多k天走完全程,除第k天外,每一天小 Y 都必须在休息站过夜。所以,一段路必须在同一天走完。
小 Y 的体力有限,他希望走的路程最大的一天中走的路尽可能少,请求出这个最小值。
Input
第一行三个整数n、m、k表示图的顶点数、边数、天数。
从第二行开始,之后的m行,每行三个整数ui、vi、wi表示从ui和vi间有一条双向道路,长度为wi。
Output
一行一个正整数,如果小 Y 能走完全程,输出走的路程最大的一天中走的路程最小值,否则输出-1。
Example
graph.in
3 2 4
3 2 4
1 2 1
graph.out
4
附加样例见选手目录下『graph』文件夹。
Hint
对于10%的数据,m=0;
对于30%的数据,n,m,k<=10 ;
对于100%的数据,2<=n<=k<=7500,0<=m<=200000,1<=wi<=10^9;
保证没有重边和自环。

graph_数据graph_i++_02
分析:刚开始没有看到题目中k<n,所以以为一天可以走多条路,做了一个spfa的预处理,处理出一个点到所有点的距离,然后空间爆了。其实一天只走一条路,那就简单多了。可以二分答案+spfa来做,90分,有一个点超时。
      然后又用最小瓶颈生成树打了一遍。

AC代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#define N 7510
#define M 200010
using namespace std;
struct node
{
    int x,y,z;
};node e[M];
int fa[N],m,n,p;
bool cmp(const node&a,const node&b)
{
    return a.z<b.z;
}
int find(int x)
{
    if(fa[x]==x)return x;
    return fa[x]=find(fa[x]);
}
int main()
{
    freopen("graph.in","r",stdin);
    freopen("graph.out","w",stdout);
    scanf("%d%d%d",&n,&m,&p);
    for(int i=1;i<=n;i++)
      fa[i]=i;
    for(int i=1;i<=m;i++)
      scanf("%d%d%d",&e[i].x,&e[i].y,&e[i].z);
    sort(e+1,e+m+1,cmp);
    bool flag=false;int tot=0;
    for(int i=1;i<=m;i++)
    {
        int a=find(e[i].x),b=find(e[i].y);
        if(a!=b)
        {
            fa[a]=b;
            tot++;
        }
        if(find(1)==find(n))
        {
            printf("%d",e[i].z);
            flag=true;
            break;
        }
        if(tot==n-1)break;
    }
    if(!flag)printf("-1");
    return 0;
}
View Code