比赛描述
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]); } }