【最大生成树+倍增】NOIP 2013 货车运输
2017-10-17 15:55
375 查看
题面在这里
考虑每次都应该走尽可能大的路
对于任意两个联通块也是如此,可以只保留边权最大的那条边来连接这两个联通块
那么就是最大生成树了
每次询问就是在树上询问最小的边权,倍增一发就好了
示例程序:
考虑每次都应该走尽可能大的路
对于任意两个联通块也是如此,可以只保留边权最大的那条边来连接这两个联通块
那么就是最大生成树了
每次询问就是在树上询问最小的边权,倍增一发就好了
示例程序:
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; inline char nc(){ static char buf[100000],*p1=buf,*p2=buf; return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++; } inline int red(){ int res=0,f=1;char ch=nc(); while (ch<'0'||'9'<ch) {if (ch=='-') f=-f;ch=nc();} while ('0'<=ch&&ch<='9') res=res*10+ch-48,ch=nc(); return res*f; } const int maxn=10005,maxe=50005,INF=0x3f3f3f3f; int n,lgn,e,q,fa[maxn]; struct data{ int x,y,w; bool operator<(const data&b)const{ return w>b.w; } }a[maxe]; int tot,son[maxe],nxt[maxe],lnk[maxn],w[maxe]; inline void add(int x,int y,int z){ son[++tot]=y;nxt[tot]=lnk[x];lnk[x]=tot;w[tot]=z; } int getfa(int x){ return fa[x]==x?x:fa[x]=getfa(fa[x]); } int f[maxn][15],g[maxn][15],dep[maxn]; bool vis[maxn]; void dfs(int x,int fa){ vis[x]=1;dep[x]=dep[fa]+1; for (int j=lnk[x];j;j=nxt[j]) if (son[j]!=fa){ f[son[j]][0]=x;g[son[j]][0]=w[j]; dfs(son[j],x); } } void DP(){ for (int j=1;j<=lgn;j++) for (int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1], g[i][j]=min(g[i][j-1],g[f[i][j-1]][j-1]); } int query(int x,int y){ if (dep[x]<dep[y]) swap(x,y); int res=INF; for (int j=lgn;j>=0;j--) if (dep[f[x][j]]>=dep[y]) res=min(res,g[x][j]),x=f[x][j]; if (x==y) return res; for (int j=lgn;j>=0;j--) if (f[x][j]!=f[y][j]) res=min(res,min(g[x][j],g[y][j])),x=f[x][j],y=f[y][j]; if (f[x][0]!=f[y][0]) return -1; return min(res,min(g[x][0],g[y][0])); } int main(){ n=red(),e=red();lgn=log2(n); for (int i=1;i<=e;i++) a[i].x=red(),a[i].y=red(),a[i].w=red(); sort(a+1,a+1+e); for (int i=1;i<=n;i++) fa[i]=i; for (int i=1;i<=e;i++){ if (getfa(a[i].x)==getfa(a[i].y)) continue; fa[getfa(a[i].x)]=getfa(a[i].y); add(a[i].x,a[i].y,a[i].w);add(a[i].y,a[i].x,a[i].w); } for (int i=1;i<=n;i++) if (!vis[i]) f[i][0]=i,g[i][0]=INF,dfs(i,0); DP(); q=red(); for (int i=1;i<=q;i++){ int x=red(),y=red(); printf("%d\n",query(x,y)); } return 0; }
相关文章推荐
- codevs 3287||NOIP 2013 货车运输 最大生成树+倍增 解题报告
- 洛谷 1967 [NOIP2013] 货车运输 最大生成树+倍增
- 【题】【树(最大生成树&LCA)】NKOJ 2495 货车运输 【NOIP2013-D1T3】
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
- NOIP2013货车运输(最大生成树+LCA)
- NOIP2013 货车运输 [LCA+最大生成树]
- NOIP2013 货车运输 (最大生成树+树上倍增LCA)
- [noip2013] 货车运输(最大生成树+并查集+LCA)
- NOIP 2013 CODE[VS] 3287 货车运输 倍增LCA || 暴力LCA + 最大生成树
- 【NOIP2013提高组T3】货车运输-最大生成树+倍增LCA
- NOIP2013货车运输 (最大生成树,分块求LCA)
- 【NOIP 2013 Day1 T3】货车运输(最大生成树+LCA)
- [NOIP2013] 货车运输 最大生成树 LCA
- noip2013货车运输 最大生成树+LCA 【pascal】
- [NOIP2013]货车运输,最大生成树+LCA
- NOIP 2013 CODE[VS] 3287 货车运输 倍增LCA + 最大生成树
- noip2013 货车运输 (求解生成树路径上的最短边:倍增求最近共祖先+最大生成树Kruskal)
- NOIP2013 货车运输 解题报告(最大生成树+倍增lca)
- [NOIP2013]货车运输 D1 T3 kruscal最大生成树+树上倍增lca+rmq
- NOIP2013 货车运输(最大生成树+LCA)