zoukankan      html  css  js  c++  java
  • 【NOIP2013提高组】DAY1T3—货车运输(Kruscal重构树)

    描述
    A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物?
    输入
    输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道
    路。 接下来 m 行每行 3 个整数 x、 y、 z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意: x 不等于 y,两座城市之间可能有多条道路 。
    接下来一行有一个整数 q,表示有 q 辆货车需要运货。
    接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意: x 不等于 y 。
    输出
    每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货
    车不能到达目的地,输出-1。
    样例输入
    4 3
    1 2 4
    2 3 3
    3 1 1
    3
    1 3
    1 4
    1 3
    样例输出
    3
    -1
    3
    提示
    对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q< 1,000;
    对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q< 1,000;
    对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q< 30,000,0 ≤ z ≤ 100,000。

    貌似最小生成树就搞定了啊,这么水的吗

    但我就要练KruscalKruscal重构树你管我?

    #include<bits/stdc++.h>
    using namespace std;
    #define mod 1000000007
    #define ll long long
    inline int read(){
        char ch=getchar();
        int res=0;
        while(!isdigit(ch))ch=getchar();
        while(isdigit(ch)) res=(res<<3)+(res<<1)+(ch^48),ch=getchar();
        return res;
    }
    int adj[370005],nxt[340005],to[340005],dep[370005],val[340005],cnt,tot,fa[370005],son[370005],fath[370005],siz[370005],n,m,q,top[370005];
    struct edge{
    	int u,v,w;
    }e[100006];
    ll A,B,C,P,ans;
    inline int rnd(){
    	return A=(A*B+C)%P;
    }
    inline bool comp(const edge &a,const edge &b){
    	return a.w>b.w;
    }
    inline void addedge(int u,int v){
    	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v;
    	nxt[++cnt]=adj[v],adj[v]=cnt,to[cnt]=u;
    }
    inline void dfs1(int u,int father){
    	siz[u]=1;
    	for(int e=adj[u];e;e=nxt[e]){
    		int v=to[e];
    		if(v==father)continue;
    		fa[v]=u;
    		dep[v]=dep[u]+1;
    		dfs1(v,u);
    		siz[u]+=siz[v];
    		if(siz[v]>siz[son[u]])son[u]=v;
    	}
    }
    inline void dfs2(int u,int tp){
    	top[u]=tp;
    	if(son[u])dfs2(son[u],tp);
    	for(int e=adj[u];e;e=nxt[e]){
    		int v=to[e];
    		if(v==fa[u]||v==son[u])continue;
    		dfs2(v,v);
    	}
    }
    inline int find(int x){
    	return fath[x]==x?x:fath[x]=find(fath[x]);
    }
    inline int lca(int u,int v){
    	while(top[u]!=top[v]){
    		if(dep[top[u]]>dep[top[v]])u=fa[top[u]];
    		else v=fa[top[v]];
    	}
    	if(dep[u]<dep[v])return u;
    	return v;
    }
    int main(){
    	tot=n=read(),m=read();
    	for(int i=1;i<=n;++i)fath[i]=i;
    	for(int i=1;i<=m;++i){
    		e[i].u=read(),e[i].v=read(),e[i].w=read();
    	}
    	sort(e+1,e+1+m,comp);
    	for(int i=1;i<=m;++i){
    		int f1=find(e[i].u),f2=find(e[i].v);
    		if(f1!=f2){
    			fath[f1]=fath[f2]=fath[++tot]=tot;
    			val[tot]=e[i].w;
    			addedge(f1,tot),addedge(f2,tot);
    		}
    	}
    	dfs1(tot,0),dfs2(tot,tot);
    	q=read();
    	for(int i=1;i<=q;++i){
    		int u=read(),v=read();
    		if(find(u)==find(v))
    		cout<<val[lca(u,v)]<<endl;
    		else cout<<"-1"<<'
    ';
    	}
    }
    
  • 相关阅读:
    jquery获取父元素或父节点的方法
    JS省份联级下拉框
    全国各省、市名称(包括县级市)
    让Vs2010支持 Css3+HTML5
    Sql Server 事务/回滚
    Windows.Forms Panel 动态加载用户控件 UserControl
    C/C++ 运算符 & | 运算
    WPF
    SQL Server 数据库定时自动备份【转】
    如何编写更棒的代码:11个核心要点
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/10366332.html
Copyright © 2011-2022 走看看