Little Q is crazy about graph theory, and now he creates a game about graphs and trees.
There is a bi-directional graph with nn nodes, labeled from 0 to n−1n−1. Every edge has its length, which is a positive integer ranged from 1 to 9.
Now, Little Q wants to delete some edges (or delete nothing) in the graph to get a new graph, which satisfies the following requirements:
(1) The new graph is a tree with n−1n−1 edges.
(2) For every vertice v(0<v<n)v(0<v<n), the distance between 0 and vv on the tree is equal to the length of shortest path from 0 to vv in the original graph.
Little Q wonders the number of ways to delete edges to get such a satisfied graph. If there exists an edge between two nodes ii and jj, while in another graph there isn't such edge, then we regard the two graphs different.
Since the answer may be very large, please print the answer modulo 109+7109+7.
InputThe input contains several test cases, no more than 10 test cases.
There is a bi-directional graph with nn nodes, labeled from 0 to n−1n−1. Every edge has its length, which is a positive integer ranged from 1 to 9.
Now, Little Q wants to delete some edges (or delete nothing) in the graph to get a new graph, which satisfies the following requirements:
(1) The new graph is a tree with n−1n−1 edges.
(2) For every vertice v(0<v<n)v(0<v<n), the distance between 0 and vv on the tree is equal to the length of shortest path from 0 to vv in the original graph.
Little Q wonders the number of ways to delete edges to get such a satisfied graph. If there exists an edge between two nodes ii and jj, while in another graph there isn't such edge, then we regard the two graphs different.
Since the answer may be very large, please print the answer modulo 109+7109+7.
In each test case, the first line contains an integer n(1≤n≤50)n(1≤n≤50), denoting the number of nodes in the graph.
In the following nn lines, every line contains a string with nn characters. These strings describes the adjacency matrix of the graph. Suppose the jj-th number of the ii-th line is c(0≤c≤9)c(0≤c≤9), if cc is a positive integer, there is an edge between ii and jjwith length of cc, if c=0c=0, then there isn't any edge between ii and jj.
The input data ensure that the ii-th number of the ii-th line is always 0, and the jj-th number of the ii-th line is always equal to the ii-th number of the jj-th line.OutputFor each test case, print a single line containing a single integer, denoting the answer modulo 109+7109+7.Sample Input
2 01 10 4 0123 1012 2101 3210Sample Output
1 6
思路:
求出0到每个点的最短路的不同路径数,然后要形成一棵树,根据乘法原理,把所有路径种类相乘就行了。
代码:
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
const int maxn=3000;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
struct node
{
int to;
int va;
int next;
}edge[maxn];
int dis[maxn],vis[maxn],head[maxn],an[maxn];
queue<int>Q;
int ans=0;
int n;
void add(int u,int v,int w)
{
edge[ans].to=v;
edge[ans].va=w;
edge[ans].next=head[u];
head[u]=ans++;
}
void init()
{
ans=0;
memset(vis,0,sizeof(vis));
memset(head,-1,sizeof(head));
memset(an,0,sizeof(an));
}
void spfa()
{
for(int i=1;i<=n;i++)dis[i]=INF;
while(!Q.empty())Q.pop();
Q.push(0);
dis[0]=0;
vis[0]=1;
while(!Q.empty())
{
int u=Q.front();Q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=edge[i].next)
{
node e=edge[i];
int v=e.to;
if(dis[v]==dis[u]+e.va)an[v]++;
if(dis[v]>dis[u]+e.va)
{
dis[v]=dis[u]+e.va;
//cout<<an[v]<<endl;
if(!vis[v])
{
vis[v]=1;
Q.push(v);
}
}
}
}
}
char a[maxn][maxn];
int main()
{
while(~scanf("%d",&n))
{
init();
for(int i=0;i<n;i++)
{
scanf("%s",a[i]);
for(int j=0;j<n;j++)
{
if(i==j)continue;
add(i,j,a[i][j]-'0');
}
}
spfa();
for(int i=1;i<n;i++)
{
an[i]++;
}
long long sum=1;
for(int i=1;i<n;i++)
{
//printf("%d\n",an[i]);
sum=(sum*an[i])%mod;
}
printf("%lld\n",sum);
}
return 0;
}