南邮 OJ 1412 商人的宣传

商人的宣传

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 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]);
	}
}





你可能感兴趣的:(ACM,南邮OJ,商人的宣传)