UCF Local Contest A Prickly Problem

 

大意:

给定一个图(边权全部=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;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值