C++标程
查看原帖
C++标程
456
lx99410楼主2014/8/1 22:43
#include<stdio.h>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=10001,maxm=50001;
const int INF=0x7fffffff;
struct Node{
    int s,t,d;
}e[maxm];
struct Edge{
    int e,v;
}tmp;
inline bool cmp(struct Node a,struct Node b){
    return a.d>b.d;
}
struct Set{
    int root[maxn];
    void init(int N){
        for(int i=1;i<=N;i++)root[i]=0;
    }
    int find(int s){
        if(root[s]==0)return s;
        int e=find(root[s]);
        return root[s]=e;
    }
    void merge(int s,int e){
        root[find(s)]=find(e);
    }
}R;
struct Truck{
    vector <struct Edge> ADJL[maxn];
    int up[maxn][20],Min[maxn][20],h[maxn],N,M,Q;
    bool f[maxn];
    void BuildTree(int v){
        f[v]=0;
        vector <struct Edge>::iterator it;
        for(it=ADJL[v].begin();it!=ADJL[v].end();it++){
          if(f[it->e]){
              up[it->e][0]=v;
              Min[it->e][0]=it->v;
              h[it->e]=h[v]+1;
              BuildTree(it->e);
          }
        }
    }
    void init(){
        scanf("%d%d",&N,&M);
        for(int i=0;i<M;i++)scanf("%d%d%d",&e[i].s,&e[i].t,&e[i].d);
        sort(e,e+M,cmp);
        R.init(N);
        for(int i=0;i<M;i++)
          if(R.find(e[i].s)!=R.find(e[i].t)){
              R.merge(e[i].s,e[i].t);
            tmp.e=e[i].t;tmp.v=e[i].d;
            ADJL[e[i].s].push_back(tmp);
            tmp.e=e[i].s;
            ADJL[e[i].t].push_back(tmp);
          }
        memset(f,true,sizeof(f));
        for(int i=0;i++<N;)
          if(f[i])h[i]=0,BuildTree(i),Min[i][0]=INF,up[i][0]=i;
        for(int i=0;i++<19;){
          for(int j=0;j++<N;){
              up[j][i]=up[up[j][i-1]][i-1];
              Min[j][i]=min(Min[j][i-1],Min[up[j][i-1]][i-1]);
          }
        }
    }
    int Move(int &v,int H){
      int rec=INF;
      for(int i=19;i>=0;i--){
        if(h[up[v][i]]>=H){
          rec=min(rec,Min[v][i]);
          v=up[v][i];
        }
      }
      return rec;
    }
    int solve(int u,int v){
      if(R.find(u)!=R.find(v))return -1;
       int rec=INF;
      if(h[u]!=h[v])rec=h[u]>h[v]?Move(u,h[v]):Move(v,h[u]);
      if(u==v)return rec;
      for(int i=19;i>=0;i--){
        if(up[u][i]!=up[v][i]){
          rec=min(rec,min(Min[u][i],Min[v][i]));
          u=up[u][i],v=up[v][i];
        }
      }
      rec=min(rec,min(Min[u][0],Min[v][0]));
      return rec;
    }
    void work(){
        scanf("%d",&Q);
        while(Q--){
          int u,v;
          scanf("%d%d",&u,&v);
          printf("%d\n",solve(u,v));
        }
    }
}sol;
int main(){
    sol.init();
    sol.work();
    return 0;
}
2014/8/1 22:43
加载中...