zoukankan      html  css  js  c++  java
  • 可达?

    可达?

    题目描述

    小明有一张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
    ",bit[i].count());
    	}
    	return 0;
    }
    
  • 相关阅读:
    struts2解决动态多文件上传的问题(上传文件与数据库字段一一对应)(转)
    Android应用如何开机自启动、自启动失败原因
    android操作ini工具类
    C++#define的用法(含特殊)
    c指针
    WP7备注(34)(UpdateSourceTrigger|ValidatesOnExceptions|NotifyOnValidationError)
    WP7备注(30)(数据绑定基本)
    WP7备注(38)(VisualStateManager)
    WP7备注(39)(ResourceDictionary)
    WP7备注(35)(Vector Graphics|Raster Graphics)
  • 原文地址:https://www.cnblogs.com/LeafLove/p/12382832.html
Copyright © 2011-2022 走看看