本文含有原创题,涉及版权利益问题,严禁转载,违者追究法律责任
本来是写个 DP 分分钟就 A 了,结果老师要我们写记忆化搜索(无奈脸)
算啦,随手一改又是一个标准的记忆化搜索(目测好像是记忆化搜索容易码一些,而且跑得快一些)
话说不取模也可以A,数据太水
很水的题吧,先 SPFA 跑一遍 2 的最短路,然后记忆化搜索统计方案
不难证明在加上最短路的限制条件后,图变成了一个 DAG
证明:首先有向是显然的,不可能存在两点 x,y,它们的最短路 d[x]>d[y] 又 d[x]<d[y]
若存在一个环 a→b→c→a ......
则 d[a]>d[b],d[b]>d[c],d[c]>d[a],这个式子显然是不成立的
证毕
代码很容易打,加了读入优化
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #include<queue> 8 using namespace std; 9 10 const int N=50001,M=100001,mo=1000000009,oo=2147483647; 11 int v[M*2],w[M*2],next[M*2],first[N],d[N],f[N]; 12 bool g[N]; 13 queue<int> q; 14 inline int read() 15 { 16 int re=0; 17 char ch=getchar(); 18 while (ch<'0'||ch>'9') ch=getchar(); 19 while (ch>='0'&&ch<='9') 20 { 21 re=re*10+ch-'0'; 22 ch=getchar(); 23 } 24 return re; 25 } 26 inline int dfs(int x,int fa) 27 { 28 if (g[x]) return f[x]; 29 g[x]=1; 30 int k; 31 for (int i=first[x];i;i=next[i]) 32 { 33 k=v[i]; 34 if (k==fa||d[k]<=d[x]) continue; 35 if ((f[x]+=dfs(k,x))>=mo) f[x]-=mo; 36 } 37 return f[x]; 38 } 39 int main() 40 { 41 freopen("mod.in","r",stdin); 42 freopen("mod.out","w",stdout); 43 int n,m,i,k,x,j; 44 n=read(); 45 m=read(); 46 for (i=1;i<=m;i++) 47 { 48 v[i+m]=x=read(); 49 v[i]=read(); 50 w[i+m]=w[i]=read(); 51 next[i]=first[x]; 52 first[x]=i; 53 next[i+m]=first[v[i]]; 54 first[v[i]]=i+m; 55 } 56 for (i=1;i<=n;i++) d[i]=oo; 57 q.push(2); 58 d[2]=0; 59 while (!q.empty()) 60 { 61 x=q.front(); 62 q.pop(); 63 f[x]=0; 64 for (i=first[x];i;i=next[i]) 65 { 66 k=v[i]; 67 if (d[k]>d[x]+w[i]) 68 { 69 d[k]=d[x]+w[i]; 70 if (!f[k]) 71 { 72 f[k]=1; 73 q.push(k); 74 } 75 } 76 } 77 } 78 f[1]=1; 79 printf("%d ",dfs(2,0)); 80 return 0; 81 }
本题是原创题,可购买数据(10个测试点),RMB 1.5
如需购买者,联系方式戳这里 http://www.cnblogs.com/hadilo/p/5932395.html