zoukankan      html  css  js  c++  java
  • 2101 可达性统计(拓扑排序/dfs+状态压缩)

    【题目描述】

    	给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量。N,M≤30000。
    

    【题目链接】

    2101 可达性统计

    【算法】

    拓扑排序之后逆序计算(感觉dfs更好写而且应该更快一点),bitset状态压缩模拟集合的并操作。

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,tot,cnt;
    struct edge{ int to,next; }e[30010];
    int head[30010],topn[30010],deg[30010];
    bitset <30010> s[30010];
    inline int read() {
        int x=0,f=1; char c=getchar();
        while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); }
        while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); }
        return x*f;
    }
    void add(int x,int y) {
        e[++tot].to=y,e[tot].next=head[x];
        head[x]=tot,deg[y]++;
    }
    void topsort() {
        queue<int> q;
        for(int i=1;i<=n;i++) if(!deg[i]) q.push(i);
        while(q.size()) {
            int x=q.front(); q.pop();
            topn[++cnt]=x;
            for(int i=head[x];i;i=e[i].next) {
                int to=e[i].to; deg[to]--;
                if(!deg[to]) q.push(to);
            }
        }
    }
    int main() {
        n=read(),m=read();
        for(int i=1;i<=m;i++) {
            int a,b;
            a=read(),b=read();
            add(a,b);
        }
        topsort();
        for(int i=cnt;i>=1;i--) {
            int x=topn[i];
            s[x][x]=1;
            for(int j=head[x];j;j=e[j].next) {
                int to=e[j].to;
                s[x]|=s[to];
            }
        }
        for(int i=1;i<=n;i++) printf("%d
    ",s[i].count());
        return 0;
    }
    
  • 相关阅读:
    POJ 2253 Frogger
    C++map函数的用法
    蓝桥杯 幂方分解
    蓝桥杯 危险系数
    POJ 2234 Matches Game
    POJ 1852 Ants
    POJ 1144 Network
    POJ1419 Graph Coloring
    poj 2573 Bridge(有A、B、C、D四个人,要在夜里过一座桥……)
    小知识(输出源文件的标题和目前执行行的行数)
  • 原文地址:https://www.cnblogs.com/Willendless/p/9514511.html
Copyright © 2011-2022 走看看