2017 Wuhan University Programming Contest (Online Round)
Input file: standard input
Output file: standard output
Time limit: 1 second
Memory limit: 512 mebibytes
As one of the most beautiful campus in China, Wuhan University is around several hills, so the road is complex and visitors always lose themselves. Give a undirected graph of WHU of NN points and a deadline, then you should count the number of plan to reach the destination by deadline (the starting point is 1 and the ending point is NN).
Input
First line contains the number of points NN (Nle 100N≤100) and the number of edges MM (Mle N(N-1)/2M≤N(N−1)/2).
The ii-th line of next MM lines contains two numbers u_iu
i
and v_iv
i
, which respents an edge (u_i, v_i)(u
i
,v
i
).
The last line contains the deadline TT(Tle 10^9T≤10
9
).
Output
The number of plan to reach the destination by deadline module 10^9+710
9
+7.
Examples
Input 1
4 5
1 3
2 3
3 4
1 2
1 4
8
Output 1
170
注意:数组开LL, mod = 1e9+7;
题意:给你n个点,m条路,以及时间t,求在时间t内到达n点的方法总数;
有两点需要理解。
一:到达终点后不能继续走了,所以mt[n][i]=0;
二:只有把mt[n][n]=1,求出来的才是在时间k内能走到终点的所有方法。
举个例子
比如说有这样一组数据
1 4
1 2
2 3
2 4
3 4
3
然后构造初始矩阵A
0 1 0 1
1 0 1 1
0 1 0 1
0 0 0 1
上面的mat[1][n]代表1到n需要走1单位时间的路径有几条
然后是矩阵A^2
1 0 1 2
0 2 0 3
1 0 1 2
0 0 0 1
这里第一行代表点1到点j需要走2单位时间的路径有几条
最后一列代表点i到点n需要走<=2单位时间的路径有几条(这里就是令mat[n][n]=1的妙处了)
矩阵A^3
0 2 0 4
2 0 2 5
0 2 0 4
0 0 0 1
在矩阵A^3中mat[1][n]=4,所以答案就是4了(具体详见代码)
ps:想一下矩阵是怎么乘的,就应该理解·了,我是这样理解的.(a[1][n]乘以a[n][n],才能加上小于k时间的方法,如果a[n][n]=0就加不上了,我是这样理解的)
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
#define mem(a,b) memset(a,b,sizeof(a))
#define LL long long int
const int mod=1000000000+7;
int n,m;
struct mat
{
LL mt[105][105];
mat()
{
memset(mt,0,sizeof(mt));
}
};
mat I;
mat cheng(mat q,mat p)
{
mat c;
mem(c.mt,0);
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
for(int k=0; k<n; k++)
{
c.mt[i][j]=(c.mt[i][j]+q.mt[i][k]*p.mt[k][j])%mod;
}
return c;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
mat ans;
mem(ans.mt,0);
for(int i=0; i<m; i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(x!=n) ans.mt[x-1][y-1]=1;//到达n后不能再走
if(y!=n) ans.mt[y-1][x-1]=1;//到达n后不能再走
}
ans.mt[n-1][n-1]=1;//计算<=k步的路径总数,如果为0,则计算=k时的路径数
int k;
scanf("%d",&k);
I=ans;
mem(ans.mt,0);
for(int i=0; i<n; i++)
ans.mt[i][i]=1;
while(k)
{
if(k&1) ans=cheng(ans,I);
I=cheng(I,I);
k>>=1;
}
printf("%lld
",ans.mt[0][n-1]);
}
return 0;
}