BZOJ 3732 Network

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3732 Network相关的知识,希望对你有一定的参考价值。

2016.1.28 纪念我BZOJ第一题

 

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 < = 15,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

 
 
很简单的啦~先构造个最小生成树呗,然后a到b的路径上的最长边就是答案咯~想想就明白的啦~
LCA嘛~
 
AC代码:
技术分享
/**************************************************************
    Problem: 3732
    User: cscscs
    Language: C++
    Result: Accepted
    Time:224 ms
    Memory:5036 kb
****************************************************************/
 
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int maxlog=15;
inline int read();
struct data
{
    int a,b,c;
    bool operator<(data d)const {return c<=d.c;}
}Edge[30005];
int n,m,k,father[15005]; 
int last[60005],to[60005],w[60005],final[15005],e,vis[15005];
int f[15005][maxlog],dist[15005][maxlog],dep[15005];
int FindFather(int x)
{
    if(x==father[x]) return x;
    return father[x]=FindFather(father[x]);
}
void AddEdge(int a,int b,int c)
{
    w[++e]=c;to[e]=b;last[e]=final[a];final[a]=e;
    w[++e]=c;to[e]=a;last[e]=final[b];final[b]=e;
}
void LCA(int x)
{
    vis[x]=1;
    for(int i=1;(1<<i)<=dep[x];i++)
    {
        int c=f[x][i-1];
        f[x][i]=f[c][i-1];
        dist[x][i]=max(dist[c][i-1],dist[x][i-1]);
    }
    for(int i=final[x];i;i=last[i])
    {
        if(!vis[to[i]])
        {
            dep[to[i]]=dep[x]+1;
            f[to[i]][0]=x;
            dist[to[i]][0]=w[i];
            LCA(to[i]);
        }
    }
}
int query(int a,int b)
{
    int ret=1;
    if(dep[a]<dep[b]) swap(a,b);
    for(int i = maxlog ; i >= 0 ; i-- ) if(dep[a]-(1<<i)>=dep[b])
    {
        ret=max(ret,dist[a][i]);
        a=f[a][i];
    }
    if(a==b) return ret;
    for(int i = maxlog ; i >= 0 ; i-- ) if(dep[a] > (1<<i) && f[a][i] != f[b][i])
    {
        ret=max(ret, max(dist[a][i], dist[b][i]) );
        a=f[a][i];b=f[b][i];
    }
    return max(ret, max(dist[a][0], dist[b][0]) );
}
int main()
{
    n=read();m=read();k=read();
    for(int i=1;i<=m;i++)
    {
        Edge[i]={read(),read(),read()};
    }
    sort(Edge+1,Edge+m+1);
    for(int i=1;i<=n;i++) father[i]=i;
    for(int i=1;i<=m;i++)
    {
        int u=FindFather(Edge[i].a),v=FindFather(Edge[i].b);
        if(u!=v)
        {
            father[u]=v;
            AddEdge(Edge[i].a,Edge[i].b,Edge[i].c);
        } 
    }
    for(int i=1;i<=n;i++) if(!vis[i]) LCA(i);
    while(k--)
    {
        int x=read(),y=read();
        printf("%d\\n",query(x,y));
    }
}
//----------------------------------------------------
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<0||ch>9) {
        if(ch==-) f=-1;ch=getchar();
    }
    while(ch>=0&&ch<=9)
    {
        x=x*10+ch-0;
        ch=getchar();
    }
    return x*f;
}
View Code

 

以上是关于BZOJ 3732 Network的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3732 -- 最小生成树+倍增

bzoj 3732 Network (kruskal重构树)

BZOJ3732 Network Kruskal+倍增lca

BZOJ 3732 Network Kruskal重构树+倍增LCA

值得一做》一道类似于货车运输的题目(BZOJ3732)(easy+)

BZOJ 1208: [HNOI2004]宠物收养所