zoukankan      html  css  js  c++  java
  • 【刷题】BZOJ 3732 Network

    Description

    给你N个点的无向图 (1 <= N <= 15,000),记为:1…N。
    图中有M条边 (1 <= M <= 30,000) ,第j条边的长度为: d_j ( 1 < = d_j < = 1,000,000,000).

    现在有 K个询问 (1 < = K < = 20,000)。
    每个询问的格式是:A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

    Input

    第一行: N, M, K。
    第2..M+1行: 三个正整数:X, Y, and D (1 <= X <=N; 1 <= Y <= N). 表示X与Y之间有一条长度为D的边。
    第M+2..M+K+1行: 每行两个整数A B,表示询问从A点走到B点的所有路径中,最长的边最小值是多少?

    Output

    对每个询问,输出最长的边最小值是多少。

    Sample Input

    6 6 8
    1 2 5
    2 3 4
    3 4 3
    1 4 8
    2 5 7
    4 6 2
    1 2
    1 3
    1 4
    2 3
    2 4
    5 1
    6 2
    6 1

    Sample Output

    5
    5
    5
    4
    4
    7
    4
    5

    HINT

    1 <= N <= 15,000

    1 <= M <= 30,000

    1 <= d_j <= 1,000,000,000

    1 <= K <= 15,000

    Solution

    kruskal重构树裸题
    建出重构树之后找到两个点的 (LCA) ,其权值就是答案

    #include<bits/stdc++.h>
    #define ui unsigned int
    #define ll long long
    #define db double
    #define ld long double
    #define ull unsigned long long
    const int MAXN=15000+10,MAXM=30000+10;
    int n,m,k,e,beg[MAXN<<1],to[MAXN<<2],nex[MAXN<<2],val[MAXN<<1],Jie[20][MAXN<<1],fa[MAXN<<1],cnt,dep[MAXN<<1];
    struct node{
    	int u,v,w;
    	inline bool operator < (const node &A) const {
    		return w<A.w;
    	};
    };
    node side[MAXM];
    template<typename T> inline void read(T &x)
    {
    	T data=0,w=1;
    	char ch=0;
    	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    	if(ch=='-')w=-1,ch=getchar();
    	while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
    	x=data*w;
    }
    template<typename T> inline void write(T x,char ch='')
    {
    	if(x<0)putchar('-'),x=-x;
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    	if(ch!='')putchar(ch);
    }
    template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
    template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
    template<typename T> inline T min(T x,T y){return x<y?x:y;}
    template<typename T> inline T max(T x,T y){return x>y?x:y;}
    inline int found(int x)
    {
    	if(x!=fa[x])fa[x]=found(fa[x]);
    	return fa[x];
    }
    inline void insert(int x,int y)
    {
    	to[++e]=y;
    	nex[e]=beg[x];
    	beg[x]=e;
    }
    inline void dfs(int x,int f)
    {
    	dep[x]=dep[f]+1;
    	for(register int i=beg[x];i;i=nex[i])
    		if(to[i]!=f)dfs(to[i],x);
    }
    inline int LCA(int u,int v)
    {
    	if(dep[u]<dep[v])std::swap(u,v);
    	if(dep[u]>dep[v])
    		for(register int i=19;i>=0;--i)
    			if(dep[Jie[i][u]]>=dep[v])u=Jie[i][u];
    	if(u==v)return u;
    	for(register int i=19;i>=0;--i)
    		if(Jie[i][u]!=Jie[i][v])u=Jie[i][u],v=Jie[i][v];
    	return Jie[0][u];
    }
    int main()
    {
    	read(n);read(m);read(k);
    	for(register int i=1;i<=m;++i)
    	{
    		int u,v,w;read(u);read(v);read(w);
    		side[i]=(node){u,v,w};
    	}
    	std::sort(side+1,side+m+1);
    	cnt=n;
    	for(register int i=1;i<=n+n-1;++i)fa[i]=i;
    	for(register int i=1,u,v;i<=m;++i)
    	{
    		u=found(side[i].u),v=found(side[i].v);
    		if(u==v)continue;
    		else
    		{
    			++cnt;val[cnt]=side[i].w;
    			insert(u,cnt);insert(cnt,u);
    			insert(v,cnt);insert(cnt,v);
    			fa[u]=fa[v]=Jie[0][u]=Jie[0][v]=cnt;
    		}
    	}
    	dfs(cnt,0);
    	for(register int j=1;j<=19;++j)
    		for(register int i=1;i<=cnt;++i)Jie[j][i]=Jie[j-1][Jie[j-1][i]];
    	while(k--)
    	{
    		int u,v;read(u);read(v);
    		write(val[LCA(u,v)],'
    ');
    	}
    	return 0;
    }
    
  • 相关阅读:
    邻接表(网)
    邻接表(无向图)
    邻接表(无向图)
    邻接表(有向图)
    邻接表(有向图)
    邻接表(无向图)
    邻接表(有向图)
    邻接表(有向图)
    邻接表(网)
    完美解决循环线性操作倒计时无报错
  • 原文地址:https://www.cnblogs.com/hongyj/p/9417851.html
Copyright © 2011-2022 走看看