zoukankan      html  css  js  c++  java
  • [HAOI2006]受欢迎的牛

    题目

    bzoj1051

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath> 
    #define N 100100
    using namespace std; 
    
    int n,m,ans;
    int dfn[N],t;//每一个节点被访问的时间戳,即dfs序 
    int low[N];//low[i]所能回溯到的最早的节点的dfn值
    bool flag[N];//标记栈中的点 
    int stack[N],top;//栈,存放已经访问过的点 
    int be[N];//记录每个强连通分量 
    bool mark[N]; 
    
    int a[N],b[N],p[N],nt[N],num;
    void add(int x,int y)
    {
    	a[++num]=x;b[num]=y;
    	nt[num]=p[x];p[x]=num;
    }
    
    int cnt;
    int tarjan(int x)//当前访问节点 
    {
    	dfn[x]=low[x]=++t;
    	stack[++top]=x;
    	flag[x]=1;
    	for(int e=p[x];e;e=nt[e])
    	{
    		int k=b[e];
    		if(!dfn[k])
    		{
    			tarjan(k);
    			low[x]=min(low[x],low[k]);
    		}
    		else if(flag[k]) low[x]=min(low[x],dfn[k]);
    	}
    	if(low[x]==dfn[x])//若找到请联通分量,将其全部弹出 
    	{
    		cnt++;
    		while(flag[x])
    		{
    			int k=stack[top--];
    			flag[k]=0;
    			be[k]=cnt;
    		}
    	}
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=m;i++)
    	{
    		int x,y;scanf("%d%d",&x,&y);add(x,y);
    	}
    	for(int i=1;i<=n;i++)
    		if(!dfn[i]) tarjan(i);
    	for(int i=1;i<=m;i++)
    	{
    		if(be[a[i]]!=be[b[i]])//如果当前点能到达另一个强连通分量 
    		mark[be[a[i]]]=1;//当前点所处的强连通分量显然不满足题意 
    	}
    	int sum=0,pos;//记录出度为0的强连通分量个数与位置 
    	for(int i=1;i<=cnt;i++)
    		if(!mark[i]) {sum++;pos=i;}
    	if(sum!=1) {printf("0");return 0;}
    	for(int i=1;i<=n;i++)
    		if(be[i]==pos) ans++;
    	printf("%d",ans);
    	return 0;
    }
  • 相关阅读:
    Ubuntu将Python3软连接到Python
    装有Ubuntu的硬盘插入到电脑中无法进入
    如何更改鼠标右键新建内容
    HDU 1113 Word Amalgamation
    暴力题,速算24点
    网络营销整合
    灰色预测代码
    灾情巡视C语言代码
    灰色关联度Matlab代码
    BP神经网络代码
  • 原文地址:https://www.cnblogs.com/XYZinc/p/7615178.html
Copyright © 2011-2022 走看看