某题2

仓库
warehouse.in/.out/.cpp
【问题描述】
JD 公司是 C 国最⼤的⽹上商城。JD 公司为了保证快递质量决定⾃建
仓库,对商品进⾏配送。
已知 C 国有 n 个城市,城市间有 m 条双向道路,每条路有限重。JD
公司想修建⼀些仓库来实现对 C 国所有城市的配送,仓库必须修建在某个
城市。送达每个城市的货物可以由任意⼀个仓库发出,不过在运输途中必须
满⾜限重的要求。
现在 JD 公司的⾼管在考虑要修建多少个仓库。⾼管发现如果修建 n
个仓库,那配送的重量就不会受到道路限重的限制 (每个城市货物由本地发
出),但 JD 公司要付出修 n 个仓库的成本。如果修建 1 个仓库,那配送的重
量只能是所有道路限重的最⼩值,但 JD 公司只⽤付出修 1 个仓库的成本。
JD 公司想让你设计⼀个程序来帮助⾼管决策,q 次询问,每次询问计
算如果想配送重量为 w 的物品,⾄少需要建多少个仓库。
【输入格式】
⼀⾏三个数字 n,m,q。
接下来 m ⾏,每⾏三个数字 x,y,z。表⽰有⼀条从 x 到 y 的⽆向边,限
重为 z。
接下来 q ⾏,每⾏⼀个数字 w。
【输出格式】
输出共 q ⾏,每⾏⼀个整数表⽰答案。
【样例输入】
3 2 3
1 2 1
5
2 3 2
1
2
3
【样例输出】
1
2
3
【样例解释】
配送重量为 1 的物品,可以只修建⼀个仓库在任意⼀个城市上。
配送重量为 2 的物品,需要在城市 1 修建⼀个仓库,再修建⼀个仓库
在城市 2 或城市 3。
配送重量为 3 的物品,需要在每个城市都修建⼀个仓库。
【数据规模和约定】
对于 30% 的数据,1 ≤ n,m,q ≤ 10 3 。
对于 60% 的数据,1 ≤ n,m,q ≤ 10 4 。
对于 100% 的数据,1 ≤ n,m,q ≤ 10 5 ,1 ≤ x,y ≤ n,0 ≤ z,w ≤ 10 9 。

//绂荤嚎澶勭悊锛屼粠灏忓埌澶?
//鍋氬嚭鏈€澶х敓鎴愭爲
//棣栧厛DFS涓€閬嶏紝澶勭悊鍑鸿仈閫氬潡
//鐒跺悗鑰冭檻闄愰噸绋嶅ぇ涓€鐐?
//鎵€浠ヨ�鎶婂湪杩欎袱涓�檺閲嶄箣闂寸殑杈瑰悎骞惰仈閫氬潡
//鎵€浠ヨ�缁存姢涓€涓�帓濂藉簭鐨勮竟闆?
//姣忔�鍔犺竟鐨勬椂鍊欎簩鍒嗚竟鍦ㄨ竟闆嗙殑l,r
//杩欐牱鎬诲�鏉傚害灏辨槸O(n+m)宸﹀彸
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define N 100005
#define inf 0x7fffffff
using namespace std;

int zhe[N];
int dui[N];
int ao[N];
int ans[N];
int qu[N];
int ans1;
int xia;
bool vis[N];
int n,m,q,cnt,tot;
int head[N],f[N];
 
struct edge{
	int x,y,v;
	bool operator < (const edge & s)const {
    	return v<s.v;
    }    
}a[N<<3];

struct e{    
	int u,next,to,v;
	bool operator < (const e & s)const {
    	return to>s.to;
    }
}e[N<<2];
struct asd{
	int v,id;
	bool operator < (const asd & s)const {
    	return v>s.v;
    }
}c[N];

void Insert(int u,int v,int w){
	e[++tot].u=u;
	e[tot].v=v;
	e[tot].to=w;
}

int find(int x){
    return f[x]==x?x:f[x]=find(f[x]);
}

int main()
{
    freopen("warehouse1.in","r",stdin);
    freopen("warehouse.out","w",stdout);
    scanf("%d%d%d",&n,&m,&q);
    for(int i=1;i<=n;i++)f[i]=i; 
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);
    sort(a+1,a+m+1);
    int number=0;
    for(int i=1;i<=m;++i){
        int x=a[i].x,y=a[i].y;
        int p=find(a[i].x),q=find(a[i].y);
        if(p!=q){
            f[p]=q;Insert(x,y,a[i].v);number++;
            if(number==n-1)break;
        }
    }
    for(int i=1;i<=q;++i){
        scanf("%d",&c[i].v);
        c[i].id=i;
    }
    sort(e+1,e+n);
    sort(c+1,c+q+1);
    int lllll=1;
    for(int i=1;i<=n;++i)f[i]=i;
    ans[0]=n;
    for(int i=1;i<=q;++i){
        ans[i]=ans[i-1];
        int l=c[i].v;
        while(e[lllll].to>=l){
            int aa=e[lllll].v;
            int bb=e[lllll].u;
            if(find(aa)!=find(bb))
                ans[i]--,f[aa]=bb;
            lllll++;
        }
        zhe[c[i].id]=ans[i];
    }
    for(int i=1;i<=q;++i)
        printf("%d
",zhe[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/qdscwyy/p/7788805.html