SPOJ 104 HIGH - Highways(生成树计数 不取模)

来源:互联网 发布:js重写confirm样式 编辑:程序博客网 时间:2024/06/01 08:51

题目链接:点击打开链接

   一个有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>




0 0