CodeForces - 156D:Clues(矩阵树定理&并查集)
2018-08-21 17:07
756 查看
题意:给定N点,M边,求添加最少的边使之变为连通图的方案数。
思路:注意题目给出的M边可能带环,即最后生成的不一定是一棵树。但是影响不大。根据矩阵树定理,我们知道生成树的数量=N^(N-2),即点数^(连通数-2)。
此题把已经连通的看成一个整体,就可以得到数量为N^(cnt-2),然后考虑连通块内部的点,因为内部贡献的时候每个点都有相同的机会,所以乘内部点的个数。
注意只有一个连通块时(已经连通的情况)不乘法个数。
(只会套公式,证明我不知道啊。。。
思路:注意题目给出的M边可能带环,即最后生成的不一定是一棵树。但是影响不大。根据矩阵树定理,我们知道生成树的数量=N^(N-2),即点数^(连通数-2)。
此题把已经连通的看成一个整体,就可以得到数量为N^(cnt-2),然后考虑连通块内部的点,因为内部贡献的时候每个点都有相同的机会,所以乘内部点的个数。
注意只有一个连通块时(已经连通的情况)不乘法个数。
(只会套公式,证明我不知道啊。。。
#include<bits/stdc++.h> #define rep(i,a,b) for(int i=a;i<=b;i++) #define ll long long using namespace std; const int maxn=100010; int N,M,P,fa[maxn],num[maxn],cnt; ll ans; int find(int u){ if(u==fa[u]) return fa[u]; return fa[u]=find(fa[u]); } int main() { scanf("%d%d%d",&N,&M,&P); rep(i,1,N) fa[i]=i; rep(i,1,M){ int u,v; scanf("%d%d",&u,&v); int f1=find(u),f2=find(v); if(f1!=f2) fa[f1]=f2; } rep(i,1,N) num[find(i)]++; ans=1; rep(i,1,N) if(num[i]) cnt++,ans=ans*num[i]%P; rep(i,1,cnt-2) ans=ans*N%P; if(cnt==1) ans=1; printf("%I64d\n",ans%P); return 0; }
相关文章推荐
- 【并查集分块】Codeforces 475D CGCDSSQ
- CodeForces 115A Party(并查集)
- CodeForces - 731C Socks(并查集)(贪心)
- CodeForces - 698B Fix a Tree(并查集)
- Codeforces 228E The Road to Berland is Paved With Good Intentions 枚举dfs判断可行性 || 并查集
- CodeForces 156 C.Cipher(dp)
- Codeforces 455C —— Civilization(并查集,树上最长链)
- CodeForces - 357C Knight Tournament ——并查集优化
- 【codeforces 722C】【逆向思维 离线+并查集】C. Destroying Array 【给你n个数,每次摧毁一个,求每摧毁一个的最大连续和(被摧毁的点的两边不连续)】
- Codeforces 698C. Fix a Tree (并查集)
- codeforces-755【C思维、并查集】
- Codeforces 400 D.Dima and Bacteria(并查集+弗洛伊德)
- CodeForces - 893C Rumor(并查集,DFS)
- 文章标题 codeforces 115A:Party ( 并查集)
- CodeForces - 731C Socks(并查集)(贪心)
- CodeForces - 698B Fix a Tree(并查集)
- CodeForces 156 D.Clues(Purfer序列)
- Codeforces 300B Coach 【并查集】
- 【CodeForces】915 F. Imbalance Value of a Tree 并查集
- Codeforces 437D The Child and Zoo - 树分治 - 贪心 - 并查集 - 最大生成树