zoukankan      html  css  js  c++  java
  • 「NOIP2013」货车运输

    传送门
    Luogu

    解题思路

    首先 ( ext{Kruskal}) 一下,构造出一棵森林。
    并查集还要用来判断连通性。
    倍增 ( ext{LCA}) 的时候顺便维护一下路径最小值即可。

    细节注意事项

    • 代码稍微有点长,不要出小问题

    参考代码

    #include<cstdio>
    #include<algorithm>
    using std::sort;
    const int MAXN=1e4+10;
    const int MAXM=5*1e4+10;
    inline int min(int a,int b){return a<b?a:b;}
    inline void swap(int& a,int& b){int t=a;a=b;b=t;}
    inline int read(){
    	int s=0;bool f=false;char c=getchar();
    	while(c<'0'||c>'9')f|=(c=='-'),c=getchar();
    	while(c>='0'&&c<='9')s=(s<<3)+(s<<1)+(c^48),c=getchar();
    	return (f)?(-s):(s);
    }
    int n,m,q;
    struct edge{int u,v,w;}g[MAXM];
    inline bool cmp(edge a,edge b){return a.w>b.w;}
    int tot,ver[MAXM<<1],dis[MAXM<<1],nxt[MAXM<<1],fir[MAXN];
    inline void Add_edge(int u,int v,int w){
    	nxt[++tot]=fir[u],fir[u]=tot,ver[tot]=v,dis[tot]=w;
    	nxt[++tot]=fir[v],fir[v]=tot,ver[tot]=u,dis[tot]=w;
    }
    int dad[MAXN];
    inline int findd(int k){
    	return dad[k]==k?k:dad[k]=findd(dad[k]);
    }
    inline bool is_unionn(int u,int v){
    	return findd(u)==findd(v);
    }
    inline void unionn(int u,int v){
    	int fu=findd(u),fv=findd(v);
    	if(fu!=fv)dad[fv]=fu;
    }
    inline void Kruskal(){
    	for(int i=1;i<=n;i++)
    		dad[i]=i;
    	sort(g+1,g+m+1,cmp);
    	for(int i=1;i<=m;i++)
    		if(!is_unionn(g[i].u,g[i].v))
    			unionn(g[i].u,g[i].v),Add_edge(g[i].u,g[i].v,g[i].w);
    }
    bool vis[MAXN];
    int dep[MAXN],f[MAXN][22],w[MAXN][22];
    inline void dfs(int u){
    	vis[u]=true;
    	for(int v,i=fir[u];i;i=nxt[i])
    		if(!vis[v=ver[i]])
    			dep[v]=dep[u]+1,f[v][0]=u,w[v][0]=dis[i],dfs(v);
    }
    inline int LCA(int x,int y){
    	if(!is_unionn(x,y)) return -1;
    	int ans=2147483647;
    	if(dep[x]<dep[y])swap(x,y);
    	for(int i=20;i>=0;--i)
            if(dep[f[x][i]]>=dep[y])
                ans=min(ans,w[x][i]),x=f[x][i];
    	if(x==y) return ans;
    	for(int i=20;i>=0;--i)
    		if(f[x][i]!=f[y][i])
    			ans=min(ans,min(w[x][i],w[y][i])),x=f[x][i],y=f[y][i];
    	return min(ans,min(w[x][0],w[y][0]));
    }
    int main(){
    	n=read(),m=read();
    	for(int i=1;i<=m;i++)
    		g[i].u=read(),g[i].v=read(),g[i].w=read();
    	Kruskal();
    	for(int i=1;i<=n;i++)
    		if(!vis[i]){
    			dep[i]=1;
    			dfs(i);
    			f[i][0]=i;
    			w[i][0]=2147483647;
    		}
    	for(int i=1;i<=20;i++)
            for(int j=1;j<=n;j++)
                f[j][i]=f[f[j][i-1]][i-1],w[j][i]=min(w[j][i-1],w[f[j][i-1]][i-1]);
    	q=read();
    	for(int x,y,i=1;i<=q;i++)
    		x=read(),y=read(),printf("%d
    ",LCA(x,y));
    	return 0;
    }
    

    完结撒花 (qwq)

  • 相关阅读:
    PHP+ajaxfileupload与jcrop插件结合 完成头像上传
    MySQL字符集设置及字符转换(latin1转utf8)
    sysbench的安装和做性能测试
    MySQL字符集的一个坑
    MySQL执行计划解读
    启动InnoDB引擎的方法
    查询当前使用的默认的存储引擎
    Mysql技术内幕——InnoDB存储引擎
    Oracle Golden Gate原理简介
    在系统启动时,Windows Vista 中、 在 Windows 7 中,Windows Server 2008 中和在 Windows Server 2008 R2 中的 497 天后未关闭 TIME_WAIT 状态的所有 TCP/IP 端口
  • 原文地址:https://www.cnblogs.com/zsbzsb/p/11745779.html
Copyright © 2011-2022 走看看