链接:https://ac.nowcoder.com/acm/problem/201607
来源:牛客网
题目描述
Nancy的男朋友喜欢网络安全!
最近,一种新的DDoS——脉冲波悄然来临。其基本原理是利用不同线路服务器的延时,使得Request同时到达目标服务器,以堵塞其它正常的通讯。
不妨假设攻击者在1号节点,目标服务器在nnn号节点,其余节点(2到n-1号节点)为中继服务器。
攻击者可以在任意时间发送一个定向数据包(即规定其经过中继服务器的路线,但不同数据包的路线不能完全相同),目标服务器对这种数据包具有100%的识别率,一旦识别到这种数据包,则会屏蔽这一时刻后的所有数据包。
Nancy好奇,攻击者在最优策略下,目标服务器能够收到多少份数据包呢?
输入描述:
第一行:两个整数n,m。
接下来m行:每行三个整数x,y,z,表示节点x与y可以单向通信(x到y),耗时为z。
数据满足:3≤n≤100000,1≤m≤2000003 leq n leq 100000, 1 leq m leq 2000003≤n≤100000,1≤m≤200000,0≤z≤⌊10πe⌋0 leq z leq lfloor10^{pi e}
floor0≤z≤⌊10πe⌋,图为拓扑图(有向无环图)。
输出描述:
共一行:表示攻击者在最优策略下,目标服务器能够收到数据包的数量。
由于数量可能会很大,你只需要输出答案对20010905取模后的值。
思路
记忆化搜索:
从终点开始向起点回溯(从右向左),当是相连的边时,给边加上右边点的(dp[x])
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '
'
#define mem(a,b) memset(a,b,sizeof(a))
#define debug(case,x); cout<<case<<" : "<<x<<endl;
#define open freopen("ii.txt","r",stdin)
#define close freopen("oo.txt","w",stdout)
#define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<long long,long long> PII;
const int maxn = 1e6 + 10;
struct edge{
int to,next;
}edge[maxn];
int head[maxn],tot=0,dp[maxn];
//head=-1;
void add(int u,int v){
edge[++tot].to=v;
edge[tot].next=head[u];
head[u]=tot;
}
int dfs(int x){
if(dp[x])return dp[x];
for(int i=head[x];i;i=edge[i].next){
(dp[x]+=dfs(edge[i].to))%=20010905;
}
return dp[x];
}
int main(){
int n,m;cin>>n>>m;
for(int i=1;i<=n;++i)head[i]=-1;
for(int i=1;i<=m;++i){
int x,y,z;cin>>x>>y>>z;
add(x,y);
}
dp[n]=1;
cout<<dfs(1)<<endl;
}