zoukankan      html  css  js  c++  java
  • [并查集]JZOJ 3301 家族

    由于写这篇博文的时候OJ炸掉啦,所以只给出题目大意

    告诉你d[i]表示大小为i的联通块的权值,要求问需要删去所有权值为[l..r]的边,问使联通块权值之和>=k的最小区间(长度)

    分析

    比赛的时候自己脑抽了,没发现没二分性,不能二分……

    然后不能二分以后还没根据数据规模推断,其实m^2logn暴力就行了……扎心

    然后提到联通块必想到并查集,随便鼓捣一下就过了

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <memory.h>
    using namespace std;
    typedef long long ll;
    const int N=1e3+10;
    struct Edge {
        int u,v;
        ll w;
        friend bool operator < (Edge a,Edge b) {
            return a.w<b.w;
        }
    }g[5*N];
    int n,m;
    ll k,a[N],ans=2147483647;
    int f[N],sz[N];
    
    int Get_F(int x) {return f[x]==x?x:f[x]=Get_F(f[x]);}
    
    int main() {
        scanf("%d%d%lld",&n,&m,&k);
        for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
        for (int i=1;i<=m;i++) scanf("%d%d%lld",&g[i].u,&g[i].v,&g[i].w);
        sort(g+1,g+m+1);
        for (int i=1;i<=m;i++) {
            for (int j=1;j<=n;j++) f[j]=j,sz[j]=1;
            ll cnt=n*a[1];
            for (int j=i;j<=m;j++) {
                if (ans<=g[j].w-g[i].w) break;
                int x=Get_F(g[j].u),y=Get_F(g[j].v);
                if (x!=y) {
                    f[y]=x;
                    cnt=cnt-a[sz[x]]-a[sz[y]];
                    sz[x]+=sz[y];
                    cnt+=a[sz[x]];
                }
                if (cnt>=k) {
                    ans=min(ans,g[j].w-g[i].w);
                    break;
                }
            }
        }
        if (ans==2147483647) printf("T_T");
        else printf("%lld",ans);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    POJ 3468 A Simple Problem with Integers(线段树 区间更新)
    Windows Mobile 6.0 SDK和中文模拟器下载
    Linux学习笔记——例说makefile 头文件查找路径
    uva 11427
    腾讯2014年实习生招聘笔试面试经历
    AVC1与H264的差别
    oracle递归函数
    全部编程皆为Web编程
    JavaScript--语法2--语句结构
    JavaScript--变量和运算符
  • 原文地址:https://www.cnblogs.com/mastervan/p/11141468.html
Copyright © 2011-2022 走看看