1 solutions

  • 0
    @ 2025-11-5 20:05:40

    C++ :

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    using namespace std;
    const int N = 30010, M = 50010;
    int cnt, n, m, q;
    bool vis[N];
    struct saver {
        int u, v, w;
        void input() {
            scanf("%d%d%d", &u, &v, &w);
        }
        bool operator<(const saver& rhs) const {
            return w > rhs.w;
        }
    } s[M];
    struct UFS {
        int fa[N], n;
        void make(int n) {
            this->n = n;
            for(int i = 1; i <= n; i++) fa[i] = i;
        }
        int find(int x) {
            return x == fa[x] ? x : fa[x] = find(fa[x]);
        }
        bool Union(int a, int b) {
            a = find(a);
            b = find(b);
            if(a == b)return 0;
            fa[b] = a;
            return 1;
        }
    } ufs;
    struct Node {
        int v, w;
        Node *next;
    } e[N * 2], *head[N];
    void addedge(int u, int v, int w) {
        e[++cnt] = (Node) {
            v, w, head[u]
        };
        head[u] = &e[cnt];
    }
    void add(int u, int v, int w) {
        addedge(u, v, w);
        addedge(v, u, w);
    }
    void kruskal() {
        sort(s, s + m);
        ufs.make(n);
        int done = 0;
        for(int i = 0; i < m; i++)
            if(ufs.Union(s[i].u, s[i].v)) {
                done++;
                add(s[i].u, s[i].v, s[i].w);
                if(done == n - 1)return;
            }
    }
    int fa[N], cost[N], d[N];
    void buildtree(int u) {
        vis[u] = 1;
        for(Node *p = head[u]; p; p = p->next) {
            int v = p->v;
            if(vis[v])continue;
            fa[v] = u;
            cost[v] = p->w;
            d[v] = d[u] + 1;
            buildtree(v);
        }
    }
    /*
    int cost[N][17], fa[N][17], d[N];
    void build() {
        memset(fa, -1, sizeof(fa));
        for(int i = 1; i <= n; i++)if(fa[i][0] == -1)buildtree(i);
        for(int i=1;i<=n;i++)printf("fa[%d][0]= %d cost[%d][0]= %d\n",i,fa[i][0],i,cost[i][0]);
        for(int j = 1; (1 << j) < n; j++)
            for(int i = 1; i <= n; i++)
                if(fa[i][j - 1] != -1) {
                    fa[i][j] = fa[fa[i][j - 1]][j - 1];
                    cost[i][j] = min(cost[i][j - 1], cost[fa[i][j - 1]][j - 1]);
                    printf("fa[%d][%d]= %d cost[%d][%d]= %d\n",i,j,fa[i][j],i,j,cost[i][j]);
                }
    }
    int query(int x, int y) {
        if(d[x] < d[y])swap(x, y);
    
        int lg, ans = INT_MAX;
        for(lg = 0; (1 << lg) <= d[x]; lg++);
        lg--;
    
        for(int h = lg; h >= 0; h--)if(d[x] - (1 << h) >= d[y])x = fa[x][h], ans = min(ans, cost[x][h]);
    
        if(x == y)return x;
    
        for(int h = lg; h >= 0; h--)
            if(fa[x][h] == fa[y][h] && fa[x][h] != -1)
                x = fa[x][h], y = fa[y][h], ans = min(ans, min(cost[x][h], cost[y][h]));
    
        return fa[x][0] != fa[y][0] || fa[x][0] == -1 ? -1 : ans;
    }
    */
    void build() {
        memset(fa, -1, sizeof(fa));
        for(int i = 1; i <= n; i++)if(!vis[i])buildtree(i);
    }
    int query(int x, int y) {
        if(d[x] < d[y])swap(x, y);
        int ans = INT_MAX;
        while(d[x] > d[y])ans = min(ans, cost[x]), x = fa[x];
        if(x == y)return ans;
        while(x != y) {
            ans = min(ans, min(cost[x], cost[y]));
            x = fa[x];
            y = fa[y];
        }
        return x == -1 ? -1 : ans;
    }
    void work() {
        scanf("%d", &q);
        int x, y;
        while(q--) {
            scanf("%d%d", &x, &y);
            printf("%d\n", query(x, y));
        }
    }
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 0; i < m; i++)s[i].input();
        kruskal();
        build();
        work();
        return 0;
    }
    

    Pascal :

    type
      lu=record x,y,z:longint; end;
    var
      a:array[1..50000]of lu;
      way:array[1..20000]of lu;
      f,st,en,deep,back,long:array[1..10000]of longint;
      b:array[1..10000]of boolean;
      n,m,mm,i,f1,f2,q,x1,x2,num,min:longint;
    procedure qsorta(l,r:longint);
    var i,j,mid:longint;  t:lu;
    begin
      i:=l;  j:=r;  mid:=a[random(j-i)+i].z;
      repeat
        while a[i].z>mid do inc(i);
        while a[j].z<mid do dec(j);
        if i<=j then
          begin
            t:=a[i]; a[i]:=a[j]; a[j]:=t;
            inc(i);  dec(j);
          end;
      until i>j;
      if i<r then qsorta(i,r);
      if j>l then qsorta(l,j);
    end;
    procedure qsortw(l,r:longint);
    var i,j,mid:longint;  t:lu;
    begin
      i:=l;  j:=r;  mid:=way[random(j-i)+i].x;
      repeat
        while way[i].x<mid do inc(i);
        while way[j].x>mid do dec(j);
        if i<=j then
          begin
            t:=way[i]; way[i]:=way[j]; way[j]:=t;
            inc(i);  dec(j);
          end;
      until i>j;
      if i<r then qsortw(i,r);
      if j>l then qsortw(l,j);
    end;
    function find(x:longint):longint;
    begin
      if f[x]=x then find:=x
      else find:=find(f[x]);
      f[x]:=find;
    end;
    procedure dfs(d:longint);
    var i,v:longint;
    begin
      b[d]:=true;
      if st[d]=0 then exit;
      for i:=st[d] to en[d] do
        if not b[way[i].y] then
          begin
            v:=way[i].y;
            deep[v]:=deep[d]+1;
            back[v]:=d;
            long[v]:=way[i].z;
            dfs(v);
          end;
    end;
    begin
      randomize;
      read(n,m);
      for i:=1 to m do read(a[i].x,a[i].y,a[i].z);
      qsorta(1,m);
      for i:=1 to n do f[i]:=i;
      for i:=1 to m do
        begin
          f1:=find(a[i].x);
          f2:=find(a[i].y);
          if f1<>f2 then
            begin
              f[f2]:=f1;
              inc(num);
              inc(mm);
              way[mm].x:=a[i].x;
              way[mm].y:=a[i].y;
              way[mm].z:=a[i].z;
            end;
        end;
      for i:=1 to mm do
        begin
          way[i+mm].x:=way[i].y;
          way[i+mm].y:=way[i].x;
          way[i+mm].z:=way[i].z;
        end;
      mm:=mm*2;
      qsortw(1,mm);
      st[way[1].x]:=1;  en[way[mm].x]:=mm;
      for i:=1 to mm-1 do
        if way[i].x<>way[i+1].x then
          begin
            en[way[i].x]:=i;
            st[way[i+1].x]:=i+1;
          end;
      for i:=1 to n do
        begin
          if not b[i] then
            begin
              b[i]:=true;
              deep[i]:=1;
              dfs(i);
            end;
        end;
      read(q);
      for i:=1 to q do
        begin
          read(x1,x2);
          if find(x1)<>find(x2) then
            begin
              writeln(-1);
              continue;
            end;
          min:=maxlongint;
          while deep[x1]>deep[x2] do
            begin
              if long[x1]<min then min:=long[x1];
              x1:=back[x1];
            end;
          while deep[x2]>deep[x1] do
            begin
              if long[x2]<min then min:=long[x2];
              x2:=back[x2];
            end;
          while x1<>x2 do
            begin
              if long[x1]<min then min:=long[x1];
              if long[x2]<min then min:=long[x2];
              x1:=back[x1];
              x2:=back[x2];
            end;
          writeln(min);
        end;
    end.
    
    • 1

    Information

    ID
    19997
    Time
    1000ms
    Memory
    128MiB
    Difficulty
    (None)
    Tags
    # Submissions
    0
    Accepted
    0
    Uploaded By