codeforces 366D 并查集

//给你一个无向图,图的每条边有一个范围,所选数x要在这个范围能过这条边
//求x最大范围
//枚举所有的边的右边,对于所选右边找左边最小值,用并查集判断是否可行
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std ;
const int maxn = 1010;
int F[maxn] ;
int find(int x)
{
    if(x == F[x])return x ;
    else return F[x] = find(F[x]) ;
}
int join(int x,int y)
{
    int fx = find(x) ;
    int fy = find(y) ;
    if(fx  != fy)
    F[fx] = fy ;
}
struct node
{
    int x , y ,l ,r;
}a[maxn*3] ;
bool cmp(struct node a ,struct node b)
{
    return a.l < b.l ;
}
int  main()
{
    int n , m ;
    while(~scanf("%d%d" ,&n , &m))
    {
        int x , y , l ,r ;
        for(int i = 1;i <= m;i++)
        scanf("%d%d%d%d" ,&a[i].x , &a[i].y  ,&a[i].l ,&a[i].r) ;
        sort(a+1 ,a+1+m,cmp) ;
        int ans = 0 ;
        for(int i = 1;i <= m;i++)
        {
            for(int j = 1;j <= n;j++)
            F[j] = j ;
            for(int j = 1;j <= m;j++)
            {
                if(a[j].l > a[i].r)break;
                if(a[j].r < a[i].r)continue ;
                join(a[j].x ,a[j].y);
                if(find(1) == find(n))
                {
                    ans = max(ans , a[i].r - a[j].l + 1) ;
                    break ;
                }
            }
        }
        if(ans)printf("%d\n",ans) ;
        else puts("Nice work, Dima!");
    }
    return 0;
}



































































你可能感兴趣的:(codeforces 366D 并查集)