NC201607DDoS

链接: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}\rfloor0≤z≤⌊10πe⌋,图为拓扑图(有向无环图)。

输出描述:

共一行:表示攻击者在最优策略下,目标服务器能够收到数据包的数量。
由于数量可能会很大,你只需要输出答案对20010905取模后的值。

思路

记忆化搜索:

从终点开始向起点回溯(从右向左),当是相连的边时,给边加上右边点的\(dp[x]\)

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define DOF 0x7f7f7f7f
#define endl '\n'
#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;

}

posted @ 2020-07-18 13:40  waryan  阅读(93)  评论(0编辑  收藏  举报