题目大意:给你一张道路情况的无权有向图,请你找出从a到b中途经过k个旅游景点的道路方案数,并且结果要模除1000。
解题思路:本题之前有做过一个类似的,只不过所求的解不同,那题是求最短路。这题则是用DP,设状态dp[k][j]表示从起点到达j位置,并且中途经过k个旅游景点的方案数,则状态转移方程:dp[k][z]=(dp[k][z]+dp[k-1][j])%1000,解释:从起点到达终点如果可以直接到达就为1,这里要初始化边界dp[0][b]=1,表示不用经过任何景点就能到达,状态转移就是从中插1个,然后2个,然后...最终到达最优解。并且在写转移方程要注意的点是:当起点j和终点z连通,才能够增加方法数,类似于分步乘法的组合数原理,每次多一种路的情况把之前的方法数加上来。(好吧我也不知道在讲啥了,思路有点乱,看代码吧,我想说得是你要知道终点和起点方法数的转移这点就对了)这里之前写有个bug,想当然地想打表减少复杂度,但是始终不知道在起点不同的情况下怎么处理,然后就英勇的gg了。
AC代码如下:
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=21;
int dp[maxn][maxn],map[maxn][maxn];
int main()
{
int i,j,s,z,a,b,k,n,m;
while(~scanf("%d%d",&n,&m) && n+m)
{
memset(map,0,sizeof(map));
//无向图构建
for(i=0;i<m;i++)
{
cin>>a>>b;
map[a+1][b+1]=1;
}
cin>>s;
while(s--)
{
memset(dp,0,sizeof(dp));
scanf("%d%d%d",&a,&b,&k);
dp[0][a+1]=1;
for(i=1;i<=k;i++)
{
for(j=1;j<=n;j++)
for(z=1;z<=n;z++)
if(map[j][z])
{
dp[i][z]=(dp[i-1][j]+dp[i][z])%1000;
}
}
cout<<dp[k][b+1]<<endl;
}
}
return 0;
}
好像网上的题解大多是矩阵快速幂的解法QAQ