给你一个带权图,求从0号点出发的最短路生成树有多少种?
对于每个非源点的点i,我们考虑他在最短路树的有多少个可能的父亲,即j,满足d[j]+a[j][i]=d[i]的j的个数。又因为到j的最短路长度是一个确定值,我们总可以选这些j作为i的父亲。对于每个i,把这些可能的j的个数连乘起来就是答案了。
#include <bits/stdc++.h>
#define maxn 109
#define INF 1e9
using namespace std;
const int MOD=1000000007;
int d[maxn],n,a[maxn][maxn];
bool inq[maxn];
void spfa()
{
for(int i=0;i<n;i++)
d[i]=INF;
queue<int>Q;
d[0]=0;
Q.push(0);
while(!Q.empty())
{
int u=Q.front();
Q.pop();
inq[u]=0;
for(int v=0;v<n;v++)
{
if(u==v)
continue;
if(!a[u][v])
continue;
if(d[v]>d[u]+a[u][v])
{
d[v]=d[u]+a[u][v];
if(!inq[v])
{
inq[v]=1;
Q.push(v);
}
}
}
}
}
class TreesCount
{
public:int count(vector <string> graph)
{
n=graph.size();
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
a[i][j]=graph[i][j]-'0';
spfa();
long long ans=1,cnt=0;
for(int i=1;i<n;i++)
{
cnt=0;
for(int j=0;j<n;j++)
{
if(i==j)
continue;
if(a[i][j]==0)
continue;
if(d[j]+a[j][i]==d[i])
cnt++;
}
ans=ans*cnt%MOD;
}
return ans;
}
};