• bzoj1016


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

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

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

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

      1 const mo=31011;
      2 type node=record
      3        x,y,w:longint;
      4      end;
      5 
      6 var a:array[0..10010] of node;
      7     fa,rank,v:array[0..10010] of longint;
      8     sum,ans,k1,k2,s,i,j,n,m,p,k:longint;
      9 
     10 function getf(x:longint):longint;
     11   begin
     12     if fa[x]<>x then fa[x]:=getf(fa[x]);
     13     exit(fa[x]);
     14   end;
     15 
     16 
     17 procedure swap(var a,b:node);
     18   var c:node;
     19   begin
     20     c:=a;
     21     a:=b;
     22     b:=c;
     23   end;
     24 
     25 procedure sort(l,r:longint);
     26   var i,j,x,y:longint;
     27   begin
     28     i:=l;
     29     j:=r;
     30     x:=a[(l+r) shr 1].w;
     31     repeat
     32       while a[i].w<x do inc(i);
     33       while x<a[j].w do dec(j);
     34       if not(i>j) then
     35       begin
     36         swap(a[i],a[j]);
     37         inc(i);
     38         j:=j-1;
     39       end;
     40     until i>j;
     41     if l<j then sort(l,j);
     42     if i<r then sort(i,r);
     43   end;
     44 
     45 function calc(x:longint):longint;
     46   begin
     47     calc:=0;
     48     while x>0 do
     49     begin
     50       calc:=calc+x mod 2;
     51       x:=x shr 1;
     52     end;
     53   end;
     54 
     55 function check(p,cur:longint):longint;
     56   var i,res,tot:longint;
     57   begin
     58     for i:=1 to n do
     59       fa[i]:=i;
     60     tot:=0;
     61     res:=0;
     62     for i:=p to j-1 do
     63     begin
     64       if cur and 1=1 then
     65       begin
     66         k1:=getf(a[i].x);
     67         k2:=getf(a[i].y);
     68         if k1<>k2 then
     69         begin
     70           fa[k1]:=k2;
     71           inc(tot);
     72           res:=res+a[i].w;
     73         end;
     74       end;
     75       cur:=cur shr 1;
     76     end;
     77     for i:=1 to m do
     78     begin
     79       if a[i].w=a[j-1].w then continue;
     80       k1:=getf(a[i].x);
     81       k2:=getf(a[i].y);
     82       if k1<>k2 then
     83       begin
     84         fa[k1]:=k2;
     85         inc(tot);
     86         res:=res+a[i].w;
     87       end;
     88     end;
     89     if (res=sum) and (tot=n-1) then exit(1) else exit(0);
     90   end;
     91 
     92 begin
     93   readln(n,m);
     94   for i:=1 to m do
     95     readln(a[i].x,a[i].y,a[i].w);
     96   sort(1,m);
     97   for i:=1 to n do
     98     fa[i]:=i;
     99   rank[1]:=1;
    100   p:=1;
    101   for i:=2 to m do
    102   begin
    103     if a[i].w<>a[i-1].w then inc(p);
    104     rank[i]:=p;
    105   end;
    106   i:=0;
    107   j:=0;
    108   while i<n-1 do
    109   begin
    110     inc(j);
    111     k1:=getf(a[j].x);
    112     k2:=getf(a[j].y);
    113     if k1<>k2 then
    114     begin
    115       fa[k1]:=k2;
    116       inc(i);
    117       inc(v[rank[j]]);
    118       sum:=sum+a[j].w;
    119     end;
    120   end;
    121   if i<n-1 then
    122   begin
    123     writeln(0);
    124     halt;
    125   end;
    126   ans:=1;
    127   i:=1;
    128   while i<=m do
    129   begin
    130     j:=i+1;
    131     while a[i].w=a[j].w do inc(j);
    132     if v[rank[i]]>0 then
    133     begin
    134       s:=0;
    135       for k:=0 to 1 shl (j-i)-1 do
    136         if calc(k)=v[rank[i]] then s:=s+check(i,k);
    137       ans:=ans*s mod mo;
    138     end;
    139     i:=j;
    140   end;
    141   writeln(ans);
    142 end.
    View Code
  • 相关阅读:
    全国省市县三级数据库
    多源教学数据管理系统之团队课设博客
    1.判断字符串中的字符是否Unique
    [转载]linux防火墙基础和管理设置iptables规则
    (转)Sed使用详解
    2.判断回文(Anagrams)
    【转载】关于23 种设计模式的有趣见解
    macbook M1芯片在centos8下安装k8s笔记
    Winform 学习初级 从WebForm到WinForm
    如何建立数据模型
  • 原文地址:https://www.cnblogs.com/phile/p/4473153.html
Copyright © 2020-2023  润新知