【Bzoj3732】Network

来源:互联网 发布:最简单的js幻灯片代码 编辑:程序博客网 时间:2024/06/06 13:14

题意

给你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点的所有路径中,最长的边最小值是多少?


解析

类似于那啥货车运输,嗯,懒得倍增就打了树链剖分。


#include <cstdio>#include <algorithm>#define Rep( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i<=(i##_END);i++)#define For( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i!=(i##_END);i++)#define Lop( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i>=(i##_END);i--)#define Dnt( i , _begin , _end ) for(int i=(_begin),i##_END=(_end);i!=(i##_END);i--)using std :: max;using std :: min;const int maxx = 15000 + 25;const int maxm = 30000 + 25;const int Inf = (unsigned)(-1) >> 1;typedef int Array[maxx];int n,m,x,y,z,num,cnt,ans,tot,t;int head[maxx],to[maxm],nxt[maxm],w[maxm];int Tx[maxx<<2];Array v,top,dpt,ftr,son,size,fky,rnk;class Edges{    public:        int x;        int y;        int v;}a[maxm<<1];bool cmp(Edges a,Edges b) {return a.v < b.v;}namespace Segment_Tree{    void modify(int i,int pos,int l,int r,int k){        if(l == r) {Tx[i] = k;return;}        int mid = (l+r) >> 1;        if(pos <= mid) modify(i<<1,pos,l,mid,k);        if(pos >  mid) modify(i<<1|1,pos,mid+1,r,k);        Tx[i] = max(Tx[i<<1],Tx[i<<1|1]);    }    int Query(int i,int x,int y,int l,int r){        if(x <= l && r <= y) return Tx[i];        int ans = -Inf;        int mid = (l+r) >> 1;        if(x <= mid) ans = max(ans,Query(i<<1,x,y,l,mid));        if(y >  mid) ans = max(ans,Query(i<<1|1,x,y,mid+1,r));        return ans;    }}namespace Kruskal{    int find(int x){        return x == fky[x]? x : fky[x] = find(fky[x]);    }}namespace Cute{    using namespace Segment_Tree;    void Ins(int x,int y,int z){        to[++num] = y;w[num] = z;nxt[num] = head[x];head[x] = num;    }    void Dfs(int x){        size[x] = 1;        for(int i=head[x];i;i=nxt[i]){            if(to[i] == ftr[x]) continue;            dpt[to[i]] = dpt[x] + 1;            ftr[to[i]] = x;            v[to[i]] = w[i];            Dfs(to[i]);size[x] += size[to[i]];            if(size[to[i]] > size[son[x]]) son[x] = to[i];        }    }    void __Dfs(int x,int brn){        rnk[x] = ++cnt;top[x] = brn;        if(son[x]) __Dfs(son[x],brn);        for(int i=head[x];i;i=nxt[i])            if(to[i] != son[x] && to[i] != ftr[x])                __Dfs(to[i],to[i]);    }    int Get(int x,int y){        int ans = -Inf;        while(top[x] != top[y]){            if(dpt[top[x]] > dpt[top[y]]) std :: swap(x,y);            ans = max(ans,Query(1,rnk[top[y]],rnk[y],1,n));            y = ftr[top[y]];        }        if(rnk[x] > rnk[y]) std :: swap(x,y);        if(x != y) ans = max(ans,Query(1,rnk[x]+1,rnk[y],1,n));        return ans;    }}using namespace Kruskal;using namespace Segment_Tree;using namespace Cute;int main(){    scanf("%d%d%d",&n,&m,&t);    Rep( i , 1 , n ) fky[i] = i;    Rep( i , 1 , m ) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v);    std :: sort(a+1,a+m+1,cmp);    Rep( i , 1 , m ){        int u = find(a[i].x),v = find(a[i].y);        if(u != v){            Ins(a[i].x,a[i].y,a[i].v);            Ins(a[i].y,a[i].x,a[i].v);            fky[u] = v;            tot ++;        }        if(tot == n-1) break;    }    Dfs(1);__Dfs(1,1);    Rep( i , 1 , n ) modify(1,rnk[i],1,n,v[i]);    while( t-- ){        scanf("%d%d",&x,&y);        printf("%d\n",Get(x,y));    }    return 0;}
原创粉丝点击