商人的宣传
时间限制(普通/Java) :
1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 29 测试通过 : 16
总提交 : 29 测试通过 : 16
比赛描述
Bruce在A州成立了公司,准备宣传活动开始后的第L天到达B州进行新品拍卖,期间Bruce打算将产品拿到各个州去做推销宣传。 K国有很多个州,每个州都与其他一些州相邻,但是K国有规定:
商人只能从某些州到达另外一些州,即连通路线是单向的。
商人不允许在同一个州连续宣传两天或以上,每天宣传完必须离开该州。
商人可以多次来到同一个州进行宣传。
任务:算出AB两州之间的路线的总数。
输入
第一行包含三个整数n,m,L(1≤n,L≤100),表示n个州、m条通路,L天后必须到达B州。
接下来有m行,每行一对整数x,y(1≤x,y≤n),从x州到y州有通路。
第m+2行:1个整数k,代表有k种询问
第m+3行到m+3+k行:每行两个整数Ai,Bi(1≤Ai,Bi≤n)(1<=i<=k),即每个询问中,Ai、Bi州的位置。
输出
k个整数t,表示从Ai州到Bi州满足上述规定的路线总数。(<2^31)
样例输入
4 5 6
1 2
2 3
3 4
4 1
2 4
1
1 4
样例输出
2
提示
题目来源
JSOI2010
/*
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
long long f[105][105];
int n,m,l,q;
vector<int> g[105];
long long cal(int u,int v)
{
int i,j,k;
long long ans=0;
for(i=0;i<=l;i++)
for(j=1;j<=n;j++)
f[j][i]=0;
f[u][0]=1;
for(i=0;i<=l-1;i++)
for(j=1;j<=n;j++)
{
if(f[j][i]>0)
{
for(k=0;k!=g[j].size();k++)
f[g[j][k]][i+1]+=f[j][i];
}
}
return f[v][l];
}
void work()
{
int i,u,v;
scanf("%d%d%d",&n,&m,&l);
for(i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
}
scanf("%d",&q);
for(i=0;i<q;i++)
{
scanf("%d%d",&u,&v);
printf("%lld\n",cal(u,v));
}
}
int main()
{
work();
return 0;
}
*/
/* Time Limit Exceed at Test 1
#include<iostream>
#define MAX_N 101
int n,count;
bool a[MAX_N][MAX_N];
//先在在 i ,想去 j ,还剩 t 天
void dfs(int i,int j,int t){
if(i==j){
count++;
return;
}
if(t==0){
return;
}
t--;
for(int k=1;k<=n;k++){
if(a[i][k]){
dfs(k,j,t);
}
}
}
int main(){
int m,x,y,l,k;
scanf("%d%d%d",&n,&m,&l);
while(m--){
scanf("%d%d",&x,&y);
a[x][y] = 1;
}
scanf("%d",&k);
while(k--){
count = 0;
scanf("%d%d",&x,&y);
dfs(x,y,l);
printf("%d\n",count);
}
}
*/
/* AC 15MS
#include<iostream>
#define MAX_N 101
int a[MAX_N][MAX_N]; //a[i][j] 表示节点 i 的第 j 个可到达点,a[i][0]表示i节点的可到达点数
int dp[MAX_N][MAX_N]; //到节点 i 最多耗时 j 的走法数
int main(){
int n,m,L,x,y,k,i,j,t,p,q;
scanf("%d%d%d",&n,&m,&L);
while(m--){
scanf("%d%d",&x,&y);
a[x][++a[x][0]] = y;
}
scanf("%d",&k);
while(k--){
scanf("%d%d",&x,&y);
memset(dp,0,sizeof(dp));
dp[x][0] = 1;
for(t=0;t<L;t++){
for(i=1;i<=n;i++){
if((p=dp[i][t])>0){
q = a[i][0];
for(j=1;j<=q;j++){
dp[a[i][j]][t+1] += p;
}
}
}
}
printf("%d\n",dp[y][L]);
}
}
*/
/* 13 MS
#include<iostream>
#define MAX_N 101
int a[MAX_N][MAX_N]; //a[i][j] 表示节点 i 的第 j 个可到达点
int c[MAX_N]; //c[i]表示i节点的可到达点数
int dp[MAX_N][MAX_N]; //到节点 i 最多耗时 j 的走法数
int main(){
int n,m,L,x,y,k,i,j,t,p,q;
scanf("%d%d%d",&n,&m,&L);
while(m--){
scanf("%d%d",&x,&y);
a[x][++c[x]] = y;
}
scanf("%d",&k);
while(k--){
scanf("%d%d",&x,&y);
memset(dp,0,sizeof(dp));
dp[x][0] = 1;
for(t=0;t<L;t++){
for(i=1;i<=n;i++){
if((p=dp[i][t])>0){
q = c[i]; //减少寻址时间,提高速度
for(j=1;j<=q;j++){
dp[a[i][j]][t+1] += p;
}
}
}
}
printf("%d\n",dp[y][L]);
}
}
*/
// 18 MS
#include<iostream>
#define MAX_N 101
int a[MAX_N][MAX_N]; //a[i][j] 表示节点 i 的第 j 个前驱节点
int c[MAX_N]; //c[i]表示i节点的前驱节点数
int dp[MAX_N][MAX_N]; //到节点 i 最多耗时 j 的走法数
int main(){
int n,m,L,x,y,k,i,j,t,q;
scanf("%d%d%d",&n,&m,&L);
while(m--){
scanf("%d%d",&x,&y);
a[y][++c[y]] = x;
}
scanf("%d",&k);
while(k--){
scanf("%d%d",&x,&y);
memset(dp,0,sizeof(dp));
dp[x][0] = 1;
for(t=1;t<=L;t++){
for(i=1;i<=n;i++){
q = c[i];
for(j=1;j<=q;j++){
dp[i][t] += dp[a[i][j]][t-1];
}
}
}
printf("%d\n",dp[y][L]);
}
}