bzoj 1016 最小生成树计数
题目大意:
现在给出了一个简单无向加权图 求这个图中有多少个不同的最小生成树
如果两颗最小生成树中至少有一条边不同,则这两个最小生成树就是不同的
输出方案数对31011的模
思路:
首先我们求出这个最小生成树需要用的边,每种边权的边需要用多少个
然后因为注意到数据很小
可以直接dfs
对于每种权值的边dfs,求出该种权值的边满足最小生成树的方案有多少个
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstdlib> 6 #include<cstring> 7 #include<queue> 8 #include<map> 9 #include<vector> 10 #define ll long long 11 #define inf 2147483611 12 #define MAXN 110 13 #define MOD 31011 14 using namespace std; 15 inline int read() 16 { 17 int x=0,f=1;char ch=getchar(); 18 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 19 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 20 return x*f; 21 } 22 struct data 23 { 24 int u,v,val; 25 bool operator < (const data &a) const 26 { 27 return val<a.val; 28 } 29 }e[MAXN*20]; 30 struct edge {int l,r,num;}g[MAXN*20]; 31 int n,m,cnt,f[MAXN],kd,ans,res; 32 void add(int u,int v,int w) {e[++cnt].u=u,e[cnt].v=v,e[cnt].val=w;} 33 int find(int x,bool k) 34 { 35 if(x==f[x]) return x; 36 if(k) return f[x]=find(f[x],1); 37 else return find(f[x],0); 38 } 39 bool ok(int u,int v,int k) 40 { 41 int fa=find(u,k),fb=find(v,k); 42 if(fa==fb) return 1; 43 else {f[fa]=fb;return 0;} 44 } 45 bool kruskal() 46 { 47 cnt=0; 48 for(int i=1;i<=m;i++) 49 { 50 if(e[i].val!=e[i-1].val) g[kd].r=i-1,g[++kd].l=i; 51 if(!ok(e[i].u,e[i].v,1)) cnt++,g[kd].num++; 52 } 53 g[kd].r=m; 54 if(cnt<n-1) return 0; 55 else return 1; 56 } 57 void dfs(int k,int pos,int v) 58 { 59 if(pos==g[k].r+1) {if(v==g[k].num) res++;return ;} 60 int t=find(e[pos].u,0); 61 if(!ok(e[pos].u,e[pos].v,0)) 62 { 63 dfs(k,pos+1,v+1); 64 f[t]=t; 65 } 66 dfs(k,pos+1,v); 67 } 68 int main() 69 { 70 n=read(),m=read(); 71 int a,b,c; 72 for(int i=1;i<=m;i++) {a=read(),b=read(),c=read();add(a,b,c);} 73 for(int i=1;i<=n;i++) f[i]=i; 74 sort(e+1,e+m+1); 75 if(!kruskal()) {printf("0");return 0;} 76 for(int i=1;i<=n;i++) f[i]=i; 77 ans=1; 78 for(int i=1;i<=kd;i++) 79 { 80 res=0; 81 dfs(i,g[i].l,0); 82 (ans*=res%MOD)%=MOD; 83 for(int j=g[i].l;j<=g[i].r;j++) ok(e[j].u,e[j].v,1); 84 } 85 printf("%d",ans); 86 }