zoukankan      html  css  js  c++  java
  • BZOJ3732: Network

    BZOJ3732: 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


    题解Here!
    在$BZOJ$闲逛的时候发现了这题。
    这$TM$不是$NOIP2013 ext{货车运输}$嘛。。。
    顺手码了。。。
    然而这种沙茶题我竟然没有$1A$,真是太失败了。。。
    然后发现,我$TM$竟然手抽了,把$will$打成了$f$。。。
    手残。。。
    所以一发$Kruskal+LCA+ ext{树链剖分}$就好了。
    附代码:
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #define LSON rt<<1
    #define RSON rt<<1|1
    #define DATA(x) b[x].data
    #define LSIDE(x) b[x].l
    #define RSIDE(x) b[x].r
    #define MAXN 20010
    using namespace std;
    int n,m,q,c=1,d=1;
    int father[MAXN],head[MAXN],deep[MAXN],son[MAXN],size[MAXN],fa[MAXN],id[MAXN],top[MAXN];
    struct Tree{
    	int next,to;
    }a[MAXN<<1];
    struct Segment_Tree{
    	int data,l,r;
    }b[MAXN<<2];
    struct Edge{
    	int u,v,w;
    	bool used;
    }g[MAXN<<1];
    inline int read(){
    	int date=0,w=1;char c=0;
    	while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
    	while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
    	return date*w;
    }
    inline bool cmp(const Edge &p,const Edge &q){return p.w<q.w;}
    int find(int x){return father[x]==x?x:father[x]=find(father[x]);}
    inline void uniun(int x,int y){x=find(x);y=find(y);if(x!=y)father[y]=x;}
    inline void add(int x,int y){
    	a[c].to=y;a[c].next=head[x];head[x]=c++;
    	a[c].to=x;a[c].next=head[y];head[y]=c++;
    }
    void dfs1(int rt){
    	son[rt]=0;size[rt]=1;
    	for(int i=head[rt];i;i=a[i].next){
    		int will=a[i].to;
    		if(!deep[will]){
    			deep[will]=deep[rt]+1;
    			fa[will]=rt;
    			dfs1(will);
    			size[rt]+=size[will];
    			if(size[son[rt]]<size[will])son[rt]=will;
    		}
    	}
    }
    void dfs2(int rt,int f){
    	id[rt]=d++;top[rt]=f;
    	if(son[rt])dfs2(son[rt],f);
    	for(int i=head[rt];i;i=a[i].next){
    		int will=a[i].to;
    		if(will!=fa[rt]&&will!=son[rt])dfs2(will,will);
    	}
    }
    inline void pushup(int rt){
    	DATA(rt)=max(DATA(LSON),DATA(RSON));
    }
    void buildtree(int l,int r,int rt){
    	LSIDE(rt)=l;RSIDE(rt)=r;
    	if(l==r){
    		DATA(rt)=0;
    		return;
    	}
    	int mid=l+r>>1;
    	buildtree(l,mid,LSON);
    	buildtree(mid+1,r,RSON);
    	pushup(rt);
    }
    void update(int l,int r,int c,int rt){
    	if(l<=LSIDE(rt)&&RSIDE(rt)<=r){
    		DATA(rt)=c;
    		return;
    	}
    	int mid=LSIDE(rt)+RSIDE(rt)>>1;
    	if(l<=mid)update(l,r,c,LSON);
    	if(mid<r)update(l,r,c,RSON);
    	pushup(rt);
    }
    int query(int l,int r,int rt){
    	int ans=0;
    	if(l<=LSIDE(rt)&&RSIDE(rt)<=r)return DATA(rt);
    	int mid=LSIDE(rt)+RSIDE(rt)>>1;
    	if(l<=mid)ans=max(ans,query(l,r,LSON));
    	if(mid<r)ans=max(ans,query(l,r,RSON));
    	return ans;
    }
    void kruskal(){
    	int s=0;
    	for(int i=1;i<=m&&s<n-1;i++)
    	if(find(g[i].u)!=find(g[i].v)){
    		uniun(g[i].u,g[i].v);
    		add(g[i].u,g[i].v);
    		g[i].used=true;
    		s++;
    	}
    	for(int i=1;i<=n;i++)
    	if(!deep[i]){
    		deep[i]=1;
    		dfs1(i);
    		dfs2(i,i);
    	}
    	buildtree(1,n,1);
    	for(int i=1;i<=m;i++)
    	if(g[i].used){
    		if(deep[g[i].u]>deep[g[i].v])swap(g[i].u,g[i].v);
    		update(id[g[i].v],id[g[i].v],g[i].w,1);
    	}
    }
    void solve(int x,int y){
    	int s=0;
    	while(top[x]!=top[y]){
    		if(deep[top[x]]<deep[top[y]])swap(x,y);
    		s=max(s,query(id[top[x]],id[x],1));
    		x=fa[top[x]];
    	}
    	if(deep[x]>deep[y])swap(x,y);
    	if(x!=y)s=max(s,query(id[x]+1,id[y],1));
    	printf("%d
    ",s);
    }
    void work(){
    	int x,y;
    	while(q--){
    		x=read();y=read();
    		solve(x,y);
    	}
    }
    void init(){
    	n=read();m=read();q=read();
    	for(int i=1;i<=m;i++){
    		g[i].u=read();g[i].v=read();g[i].w=read();
    		g[i].used=false;
    	}
    	for(int i=1;i<=n;i++)father[i]=i;
    	sort(g+1,g+m+1,cmp);
    	kruskal();
    }
    int main(){
    	init();
    	work();
        return 0;
    }
    
  • 相关阅读:
    从零开始Windows环境下安装python+tensorflow
    Opencv调用深度学习模型
    python tensorflow 安装
    OpenCV3 Ref SVM : cv::ml::SVM Class Reference
    OpenCV3编程入门笔记(一)
    Tensorflow学习教程变量
    opencv3.0机器学习算法使用
    Tensorflow学习教程Fetch and Feed
    multilayer perceptrons, MLP)模型,CvANN_MLP。
    域的安装配置介绍
  • 原文地址:https://www.cnblogs.com/Yangrui-Blog/p/9508958.html
Copyright © 2011-2022 走看看