这道题主要利用了最小生成树的两个性质

  1. 最小生成树每种边权的数目固定不变

  2. 最小生成树每种边权带来的连通状况一定唯一

由于每种边权的只有不到10种,所以直接穷举然后乘法原理即可

 const mo=;
type node=record
       x,y,w:longint;
     end; var a:array[..] of node;
    fa,rank,v:array[..] of longint;
    sum,ans,k1,k2,s,i,j,n,m,p,k:longint; function getf(x:longint):longint;
  begin
    if fa[x]<>x then fa[x]:=getf(fa[x]);
    exit(fa[x]);
  end; procedure swap(var a,b:node);
  var c:node;
  begin
    c:=a;
    a:=b;
    b:=c;
  end; procedure sort(l,r:longint);
  var i,j,x,y:longint;
  begin
    i:=l;
    j:=r;
    x:=a[(l+r) shr ].w;
    repeat
      while a[i].w<x do inc(i);
      while x<a[j].w do dec(j);
      if not(i>j) then
      begin
        swap(a[i],a[j]);
        inc(i);
        j:=j-;
      end;
    until i>j;
    if l<j then sort(l,j);
    if i<r then sort(i,r);
  end; function calc(x:longint):longint;
  begin
    calc:=;
    while x> do
    begin
      calc:=calc+x mod ;
      x:=x shr ;
    end;
  end; function check(p,cur:longint):longint;
  var i,res,tot:longint;
  begin
    for i:= to n do
      fa[i]:=i;
    tot:=;
    res:=;
    for i:=p to j- do
    begin
      if cur and = then
      begin
        k1:=getf(a[i].x);
        k2:=getf(a[i].y);
        if k1<>k2 then
        begin
          fa[k1]:=k2;
          inc(tot);
          res:=res+a[i].w;
        end;
      end;
      cur:=cur shr ;
    end;
    for i:= to m do
    begin
      if a[i].w=a[j-].w then continue;
      k1:=getf(a[i].x);
      k2:=getf(a[i].y);
      if k1<>k2 then
      begin
        fa[k1]:=k2;
        inc(tot);
        res:=res+a[i].w;
      end;
    end;
    if (res=sum) and (tot=n-) then exit() else exit();
  end; begin
  readln(n,m);
  for i:= to m do
    readln(a[i].x,a[i].y,a[i].w);
  sort(,m);
  for i:= to n do
    fa[i]:=i;
  rank[]:=;
  p:=;
  for i:= to m do
  begin
    if a[i].w<>a[i-].w then inc(p);
    rank[i]:=p;
  end;
  i:=;
  j:=;
  while i<n- do
  begin
    inc(j);
    k1:=getf(a[j].x);
    k2:=getf(a[j].y);
    if k1<>k2 then
    begin
      fa[k1]:=k2;
      inc(i);
      inc(v[rank[j]]);
      sum:=sum+a[j].w;
    end;
  end;
  if i<n- then
  begin
    writeln();
    halt;
  end;
  ans:=;
  i:=;
  while i<=m do
  begin
    j:=i+;
    while a[i].w=a[j].w do inc(j);
    if v[rank[i]]> then
    begin
      s:=;
      for k:= to shl (j-i)- do
        if calc(k)=v[rank[i]] then s:=s+check(i,k);
      ans:=ans*s mod mo;
    end;
    i:=j;
  end;
  writeln(ans);
end.
04-25 17:28