2
马丹,map不太会用,看的别人的
题意:n:n个点 m:m条路 k:值,每个点有一个值,要求从起点到终点的不同方案。中间不用许出现LCM不变的情况
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
typedef long long LL;
using namespace std;
#define REPF( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i )
#define CLEAR( a , x ) memset ( a , x , sizeof a )
const int maxn=2010;
const int MOD=1e9+7;
vector<LL>v[maxn];
map<LL,LL>M;
LL dp[maxn][maxn],p[maxn],k;
int n,m;
LL gcd(LL a,LL b)
{
return b?gcd(b,a%b):a;
}
LL lcm(LL a,LL b)
{
return a/gcd(a,b)*b;
}
LL dfs(LL u,LL s)
{
// cout<<"madan "<<u<<endl;
int num=M[s];
if(dp[u][num]) return dp[u][num];
LL ret=0;
for(int i=0;i<(int)v[u].size();i++)
{
LL ed=v[u][i];
LL LCM=lcm(s,p[ed]);
if(k%LCM||LCM==s&&u!=0) continue;
ret+=dfs(ed,LCM)%MOD;
}
return dp[u][num]=ret;
}
int main()
{
LL st,ed;
while(~scanf("%d%d%lld",&n,&m,&k))
{
REPF(i,0,n) v[i].clear();
while(m--)
{
scanf("%lld%lld",&st,&ed);//wa了一个小时
v[st].push_back(ed);
}
REPF(i,1,n) scanf("%lld",&p[i]);
if(k%p[n])
{
puts("0");
continue;
}
M.clear();
v[0].push_back(1);
int cnt=0;
for(LL i=1;i*i<=k;i++)
{
if(k%i==0)
{
M[i]=cnt++;
M[k/i]=cnt++;
}
}
memset(dp,0,sizeof(dp));
dp[n][M[k]]=1;
printf("%lld\n",dfs(0,1));
}
return 0;
}