#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;
#define mod 1000000007
#define ll long long
struct node {
int v;
int next;
}e[20005];
ll dp[2005][2005];
int head[20005*3];
int n,m,k;
int val[2005];
int cnt;
map<ll,int>s;
void pre()
{
s.clear();
cnt=1;
for(int i=1;i<=k/2;i++)
if(k%i==0){
s[i]=cnt++;
}
s[k]=cnt++;
}//哈希法,,,非常牛逼的算法,,我覺得這是輔助算法裏面超級牛逼的
int add(int x,int y,int index)
{
e[index].v=y;
e[index].next=head[x];
head[x]=index++;
return index;
}
int gcd(int a,int b)
{
if(a<b)
{
int temp=a;
a=b;
b=temp;
}
if(b==0)//沒想到在這裏在了跟頭,,,一直是wa,,,,我就說嘛,,,
return a;
else
return gcd(b,a%b);
}
ll DFS(int fa,int lp)
{
if(fa==n) return lp==k;
if(dp[fa][s[lp]]!=0) return dp[fa][s[lp]];
for(int i=head[fa];i!=-1;i=e[i].next)
{
int t=e[i].v;
if(k%val[t]!=0)continue;
int mulit2=val[t]/gcd(lp,val[t])*lp;
if(mulit2==lp)continue;
if(s[lp]!=0&&mulit2<=k)
dp[fa][s[lp]]=(dp[fa][s[lp]]%mod+DFS(t,mulit2)%mod)%mod;
}
return dp[fa][s[lp]];
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
int x,y;
int index=0;
memset(head,-1,sizeof(head));
memset(dp,0,sizeof(dp));
pre();
for(int i=0;i<m;i++)
{
scanf("%d%d",&x,&y);
index=add(x,y,index);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
}
if(k%val[1]==0)
printf("%lld\n",DFS(1,val[1])%mod);
else
printf("0\n");
}
return 0;
}
zoj3644
題意大概是,,在一個圖中有n個點,,每個點有個值Pi,要你從一出發是的每次都到一個點,,然後你獲得改點的與之前你已經有的點的最小公倍數,,然後不能去已經是最小公倍數不改變的點,最後使得獲得的爲k問有多少種路徑,,錯了很多次。。。讓我很心痛這個題目是DP,,記憶化搜索,,但是其中的哈希法讓我很心痛啊,,,已經接觸了一些哈希讓我開始有了一定的瞭解,,,我相信我下次一定可以做的更好。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.