大意:
给定一个图(边权全部=1),求生成树个数(点数<=100)
思路:
生成树计数裸题。
1.基尔霍夫矩阵套板子
ll K[N][N];
ll f(){
for(int i=1;i<=n-1;i++){
for(int j=i+1;j<=n-1;j++){
while(K[j][i]){//辗转相除
ll t=K[i][i]/K[j][i];
for(int k=i;k<=n-1;k++)
K[i][k]=(K[i][k]-t*K[j][k]+mod)%mod;
swap(K[i],K[j]);
res=-res;
}
}
res=(res*K[i][i])%mod;
}
return (res+MOD)%mod;
}
int main(){
int n,m;
cin>>n>>m;
ll ans=1;
memset(K,0,sizeof(K));
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
K[x][x]++;
K[y][y]++;
K[x][y]--;
K[y][x]--;
}
cout<<f()<<endl;
return 0;
}
这种方法所适用的数据范围比较小。
2.
dfs
求出所有环的边数,相乘取模即可。
因为所有边权都相等,可以随意选一个点进行dfs ,
然后为每个搜到的点分配深度 depth
如果该点vis=0,则朝下继续搜索
否则,此时的搜索深度 dd 与原先为该点分配的深度 depthdepth 的差值即环内边数
从1号开始搜,vis【1】标记为1,分配深度为1。然后1号递归搜2号,二号深度分配为2,然后搜3号,3号会再搜4号,此时4号分配深度为4,4号会再搜一号,并试图为其分配深度5,但是1号已经访问过了,所以就发现这里有一个环,并且环的边数就为5-1=4.
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1007;
ll t;
ll n,m;
ll a,b;
vector<ll> vt[50010];
bool vis[50010];
ll dep[50010];
ll dfs(ll u,ll p,ll d){
if(vis[u]++) return max(d-dep[u],(ll)1);
dep[u]=d;
ll r=1;
for(ll v:vt[u]){
if(v==p) continue;
r=r*dfs(v,u,d+1)%mod;
}
return r;
}
int main()
{
cin>>t;
for(int z=1;z<=t;++z){
memset(dep,0,sizeof dep);
memset(vis,0,sizeof vis);
for(int i=1;i<=50000;++i) vt[i].clear();
cin>>n>>m;
for(int i=1;i<=m;++i){
cin>>a>>b;
vt[a].push_back(b);
vt[b].push_back(a);
}
cout<<"Case #"<<z<<": ";
cout<<dfs(1,-1,1)<<endl;
cout<<endl;
}
return 0;
}