1. 程式人生 > 實用技巧 >簡單分析實現運維利器---webssh終端

簡單分析實現運維利器---webssh終端

題目

正文

  • 首先,根據題目中的最左端是不會捕食其他生物的生產者,最右端是不會被其他生物捕食的消費者來講,這個通俗的來理解就是最左端是入度為\(0\)的點,最右端是出度為\(0\)的點而且並不是\(DAG\)上最長的鏈,只要滿足左右都不能再走的條件就好了
  • 那麼我們只要求出以\(i\)為結尾的鏈的個數(我們明顯可以知道鏈的根是入度為\(0\)的點)記為\(f[i]\),顯然,演算法是topo這個有趣的東西啦。
  • 最後找出所有出度為\(0\)的點\(i\),並把\(f[i]\)累加。

Code

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
using namespace std;
#define reint register int
#define ull unsigned ll
#define INF 0x3f3f3f3f
#define ll long long
#define GC getchar()
#define MOD 80112002
#define MAXM 500005
#define MAXN 5005
#define R read()
ll read(){
    char c=GC; ll s=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-f;c=GC;}
    while(c>='0'&&c<='9'){s=s*10+c-'0';c=GC;}
    return s*f;
}
int head[MAXN],tot;
struct node{
    int to,nxt;
}e[MAXM];
void add(int x,int y) { e[++tot].nxt=head[x]; e[tot].to=y; head[x]=tot; }
//正常的存圖建圖
int n,m,ans,in[MAXN],out[MAXN],f[MAXN];
queue<int> q;
//億些正經的變數
int main(){
    n=R; m=R;
    for(int i=1;i<=m;++i) { int u=R,v=R; add(v,u); ++in[u]; ++out[v]; }
    //輸入&建圖
    for(int i=1;i<=n;++i) if(!in[i]) q.push(i),f[i]=1;
    //找出入度為0的點, 也就是鏈的根
    while(!q.empty()){
        int u=q.front(); q.pop();
        //拿出來利用->丟棄
        for(int i=head[u];i;i=e[i].nxt){
            //找出u點的所有孩子
            int v=e[i].to; (f[v]+=f[u])%=MOD; --in[v];
            //更新f[v]
            if(!in[v]){
                //如果更新完畢
                q.push(v);
                //可利用->入隊
                if(!out[v]) (ans+=f[v])%=MOD;
                //如果是鏈的底, 累加
            }
        }
    }
    printf("%d",ans);
    return 0;
}