bzoj1016/luogu4208 最小生成树计数 (kruskal+暴搜)

由于有相同权值的边不超过10条的限制,所以可以暴搜

先做一遍kruskal,记录下来每个权值的边使用的数量(可以离散化一下)

可以证明,对于每个权值,所有的最小生成树中选择的数量是一样的、而且它们连成的连通块也是一样的

所以我们把每个权值的边分开暴搜所有可能的情况,最后再乘到一起就是答案

 1 #include<bits/stdc++.h>
 2 #define pa pair<int,int>
 3 #define CLR(a,x) memset(a,x,sizeof(a))
 4 using namespace std;
 5 typedef long long ll;
 6 const int maxn=110,maxm=1010,P=31011;
 7 
 8 inline ll rd(){
 9     ll x=0;char c=getchar();int neg=1;
10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
12     return x*neg;
13 }
14 
15 struct Edge{
16     int a,b;
17     ll l;
18 }eg[maxm];
19 int egh[maxn],ect;
20 int N,M,L,cnt[maxm];
21 int fa[maxn],ans,sum;
22 
23 inline bool cmp(Edge a,Edge b){return a.l<b.l;}
24 inline int getf(int x){
25     while(x!=fa[x]) x=fa[x];return x;
26 }
27 
28 void dfs(int x,int y,int n){
29     if(x>M||eg[x].l!=y){
30         if(n==cnt[y]) sum=(sum+1)%P;
31         return;
32     }
33     int aa=getf(eg[x].a),bb=getf(eg[x].b);
34     if(aa!=bb){
35         fa[aa]=bb;
36         dfs(x+1,y,n+1);
37         fa[aa]=aa;
38     }
39     dfs(x+1,y,n);
40 }
41 
42 int main(){
43     //freopen("","r",stdin);
44     int i,j,k;
45     N=rd(),M=rd();
46     for(i=1;i<=M;i++){
47         eg[i].a=rd(),eg[i].b=rd();
48         eg[i].l=rd();
49     }sort(eg+1,eg+M+1,cmp);
50     int lst=-1;
51     for(i=1,j=0;i<=M;i++){
52         if(eg[i].l!=lst) j++;
53         lst=eg[i].l,eg[i].l=j;
54     }
55     for(i=1;i<=N;i++) fa[i]=i;
56     for(i=1,j=0;i<=M;i++){
57         int x=getf(eg[i].a),y=getf(eg[i].b);
58         if(x!=y){
59             fa[x]=y;
60             j++;cnt[eg[i].l]++;
61         }
62     }
63     if(j<N-1){printf("0\n");return 0;}
64     for(i=1;i<=N;i++) fa[i]=i;
65     int ans=1;
66     for(i=1,j=0;i<=M;i++){
67         if(eg[i].l!=eg[i-1].l){
68             sum=0;dfs(i,eg[i].l,0);
69             ans=(ans*sum)%P;
70         }
71         int x=getf(eg[i].a),y=getf(eg[i].b);
72         if(x!=y){
73             fa[x]=y;j++;
74         }
75     }
76     printf("%d\n",ans);
77     return 0;
78 }

 

posted @ 2018-10-09 10:15  Ressed  阅读(175)  评论(0编辑  收藏  举报