NOIP2013 DAY1 T3

来源:互联网 发布:淘宝卖虚拟物品流程 编辑:程序博客网 时间:2024/05/16 13:49

题目链接

Kruskal+LCA求解Kruskal求最大生成树LCA查找两点间最小权值

可以参见另一题
星际导航

上代码
#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>#define MIN(a,b) a<b?a:busing namespace std;int n,m,fa[500000],khead[500000],head[500000],edge_num,t_num,deep[100009],anc[100009][21];int weight[100009][21],kruedge_num,q;struct E{    int next,to,value,from;}edge[500000],kruedge[500000];inline void Swap(int &a,int &b){    int t=a;    a=b;b=t;}bool cmp(const E &x,const E &y){    return x.value>y.value;}int Find(int x){    if(fa[x]!=x) return fa[x]=Find(fa[x]);    return x;}inline int Read(){    int x=0,flag=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-') flag=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*flag;}void addedge(int x,int y,int z){    edge[++edge_num].next=head[x];    edge[edge_num].from=x;    edge[edge_num].to=y;    edge[edge_num].value=z;    head[x]=edge_num;}void addedgekru(int x,int y,int z){    kruedge[++kruedge_num].next=khead[x];    kruedge[kruedge_num].from=x;    kruedge[kruedge_num].to=y;    kruedge[kruedge_num].value=z;    khead[x]=kruedge_num;}void Kruskal(){    sort(edge+1,edge+m+1,cmp);    int i,k=0;    for(i=1;i<=n;i++){        fa[i]=i;    }    for(i=1;i<=m;i++){        int a=edge[i].from,b=edge[i].to,v=edge[i].value;        int aa=Find(a),bb=Find(b);        if(aa!=bb){            fa[aa]=bb;            addedgekru(a,b,v);            addedgekru(b,a,v);            k++;            if(k==n-1) return;        }    }}void DFS(int x){    int i;    for(i=khead[x];i;i=kruedge[i].next){        if(kruedge[i].to==anc[x][0]) continue;        anc[kruedge[i].to][0]=x;        deep[kruedge[i].to]=deep[x]+1;        weight[kruedge[i].to][0]=kruedge[i].value;        DFS(kruedge[i].to);    }}void PRE(){    int i,j;    for(i=1;i<=n;i++){        if(!anc[i][0]){            deep[i]=1;            DFS(i);        }    }    for(j=1;(1<<j)<=n;j++){        for(i=1;i<=n;i++){            if(anc[i][j-1]){                anc[i][j]=anc[anc[i][j-1]][j-1];                weight[i][j]=MIN(weight[i][j-1],weight[anc[i][j-1]][j-1]);            }        }    }}int LCA(int x,int y){    int ans=2e9;    if(deep[x]<deep[y]) Swap(x,y);    int i;    int maxlog=floor(log(n)/log(2));    for(i=maxlog;i>=0;i--){        if(deep[x]-(1<<i)>=deep[y]){            ans=MIN(ans,weight[x][i]);            x=anc[x][i];        }    }    if(x==y) return ans;    for(i=maxlog;i>=0;i--){//        if(anc[x][i] && anc[x][i]!=anc[y][i]){            ans=MIN(ans,weight[x][i]);ans=MIN(ans,weight[y][i]);            x=anc[x][i];y=anc[y][i];        }    }    ans=MIN(ans,weight[x][0]);ans=MIN(ans,weight[y][0]);    return ans;}int main(){    freopen("truck.in","r",stdin);    freopen("truck.out","w",stdout);    n=Read();m=Read();    int i;    for(i=1;i<=m;i++){        int a=Read(),b=Read(),c=Read();        addedge(a,b,c);        //addedge(b,a,c);    }    Kruskal();    PRE();    q=Read();    for(i=1;i<=q;i++){        int a=Read(),b=Read();        int aa=Find(a),bb=Find(b);        if(aa!=bb) printf("-1\n");        else printf("%d\n",LCA(a,b));    }    return 0;}
0 0
原创粉丝点击