zoj 3644
地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4834
题意:一个有向图,从1出发,到n,初始分数是位置1的分数,每走一步,分数变为之前分数跟当前位置分数的最小公倍数,题目规定每走一步分数必须变化。求多少种方案走到n达到分数k。
mark:用bfs做的。正在处于学习STL阶段,写了很长时间。
代码:
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <iostream> #include <algorithm> #include <map> #include <queue> #include <vector> #define LL long long using namespace std; const int MOD = 1000000007; const int N = 2010; int n,m,k,cnt; int w[N],vst[N]; map <int, int> dp[N]; vector<int> vv[N]; int gcd(int m, int n) { if(n == 0) return m; return gcd(n, m%n); } int bfs() { int i,j; int ret = 0; queue<int> qq; qq.push(1); vst[1] = 1; dp[1][w[1]] = 1; map<int, int>::iterator it; while(!qq.empty()) { int q = qq.front(); qq.pop(); vst[q] = 0; if(q == n) ret = (ret+dp[q][k])%MOD; int ii = vv[q].size(); for(i = 0; i < ii; i++) { int s = vv[q][i]; for(it = dp[q].begin(); it != dp[q].end(); it++) { int tem = it->first; int ans = tem/gcd(tem, w[s])*w[s]; if(ans == tem || k%ans) continue; dp[s][ans] = (dp[s][ans]+it->second)%MOD; if(!vst[s]) { vst[s] = 1; qq.push(s); } } } dp[q].clear(); } return ret; } int main() { int i,j; while(~scanf("%d%d%d", &n, &m, &k)) { for(i = 0; i < n; i++) vv[i].clear(); int aa,bb; for(i = 0; i < m; i++) { scanf("%d%d", &aa, &bb); vv[aa].push_back(bb); } for(i = 1; i <= n; i++) scanf("%d", w+i); memset(vst, 0, sizeof(vst)); printf("%d\n", bfs()); } return 0; }