码迷,mamicode.com
首页 > 其他好文 > 详细

可达?

时间:2020-02-29 15:11:07      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:last   date   题目   bitset   graph   name   front   push   mod   

可达?

题目描述

小明有一张N个点M条边的有向无环图,他想知道从每个点出发能够到达的点的数量。N,M≤30000。

输入

第一行两个整数N,M,接下来M行每行两个整数x,y,表示从x到y的一条有向边。

输出

共N行,表示每个点能够到达的点的数量。

样例输入

10 10
3 8
2 3
2 5
5 9
5 9
2 3
3 9
4 8
2 10
4 9

样例输出

1
6
3
3
2
1
1
1
1
1

题解

对于节点x和y如果x可以到达y那么x所能到达的点为y所能到达的点加上x能到达的其他点能到达的点数,可见这是一个递推问题,我们从最末的点也就是出度为0的点开始就可以递推出所有点能到达的点的个数,所以问题变成了,找到这个递推顺序,从上面的描述可见,这个顺序就是拓扑排序序列的倒序,所以我们对原图做拓扑排序后,递推得出结果即可。当我们观察样例输出可以发现,这个题的输入存在重复,所以如果我们直接计算会出现重复,所以这题用bitset来维护答案。

/**********************************************************
* @Author:             Maple
* @Date:               2020-02-29 13:50:45
* @Last Modified by:   Maple
* @Last Modified time: 2020-02-29 14:25:15
* @Remark: 
**********************************************************/
#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define CSE(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define Abs(x) (x>=0?x:(-x))
#define FAST ios::sync_with_stdio(false);cin.tie(0);
using namespace std;

typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll , ll> pll;

const int maxn=33333;
int n,m,indegree[maxn],ans[maxn];
std::vector<int> graph[maxn];
bitset<maxn> bit[maxn];
stack<int> box;

void topsort(){//拓扑排序
    queue<int> mid;
    for(int i=1;i<=n;i++){
        if(indegree[i]==0)
            mid.push(i);
    }
    while(!mid.empty()){
        int now=mid.front();
        mid.pop();box.push(now);
        for(auto k:graph[now]){
            indegree[k]--;
            if(indegree[k]==0)
                mid.push(k);
        }
    }
    return;
}

void count(){//递推统计结果
    while(!box.empty()){
        int x=box.top();
        box.pop();
        bit[x][x]=1;
        for(auto k:graph[x]){
            bit[x]=bit[x]|bit[k];
        }
    }
    return;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.in","r",stdin);
    #endif
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int x,y;
        scanf("%d%d",&x,&y);
        graph[x].push_back(y);
        indegree[y]++;
    }
    topsort();
    count();
    for(int i=1;i<=n;i++){
        printf("%d\n",bit[i].count());
    }
    return 0;
}

可达?

标签:last   date   题目   bitset   graph   name   front   push   mod   

原文地址:https://www.cnblogs.com/LeafLove/p/12382832.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!