题目链接:点击打开链接
一个有n座城市的组成国家,城市1至n编号,其中一些城市之间可以修建高速公路。现在,需要有选择的修建一些高速公路,从而组成一个交通网络。你的任务是计算有多少种方案,使得任意两座城市之间恰好只有一条路径?
可以将问题转化到成图论模型。因为任意两点之间恰好只有一条路径,所以我们知道最后得到的是原图的一颗生成树。因此,我们的问题就变成了,给定一个无向图G,求它生成树的个数t(G)。
裸的生成树计数 不取模 贴个板子(具体的可参考 周冬论文 生成树计数及其应用)
<span style="font-family:KaiTi_GB2312;font-size:18px;">#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string.h>
#include <string>
#include <vector>
#include <queue>
#define MEM(a,x) memset(a,x,sizeof a)
#define eps 1e-8
#define MOD 10009
#define MAXN 110
#define MAXM 100010
#define INF 99999999
#define ll __int64
#define bug cout<<"here"<<endl
#define fread freopen("ceshi.txt","r",stdin)
#define fwrite freopen("out.txt","w",stdout)
using namespace std;
int Read()
{
char ch;
int a = 0;
while((ch = getchar()) == ' ' | ch == '\n');
a += ch - '0';
while((ch = getchar()) != ' ' && ch != '\n')
{
a *= 10;
a += ch - '0';
}
return a;
}
void Print(int a)
{
if(a>9)
Print(a/10);
putchar(a%10+'0');
}
int sgn(double x)
{
if(fabs(x)<eps) return 0;
if(x<0) return -1;
else return 1;
}
double b[MAXN][MAXN];
double det(double a[][MAXN],int n)
{
int i,j,k,sign=0;
double ret=1;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
b[i][j]=a[i][j];
for(i=0;i<n;i++)
{
if(sgn(b[i][i])==0)
{
for(j=i+1;j<n;j++)
if(sgn(b[j][i])!=0)
break;
if(j==n) return 0;
for(k=i;k<n;k++)
swap(b[i][k],b[j][k]);
sign++;
}
ret*=b[i][i];
for(k=i+1;k<n;k++)
b[i][k]/=b[i][i];
for(j=i+1;j<n;j++)
for(k=i+1;k<n;k++)
b[j][k]-=b[j][i]*b[i][k];
}
if(sign&1) ret=-ret;
return ret;
}
double a[MAXN][MAXN];
int g[MAXN][MAXN];
int main()
{
// fread;
int tc;
scanf("%d",&tc);
while(tc--)
{
int n,m;
scanf("%d%d",&n,&m);
MEM(g,0);
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
u--; v--;
g[u][v]=g[v][u]=1;
}
MEM(a,0);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(i!=j&&g[i][j])
{
a[i][i]++;
a[i][j]=-1;
}
double ans=det(a,n-1);
printf("%.0lf\n",ans);
}
return 0;
}
</span>