zoukankan      html  css  js  c++  java
  • CF999E Solution

    题目链接

    题解

    可以发现,在一个强连通分量中,只要一个节点可以到达(s)节点,所有节点均可以到达。因此将强连通分量缩点,入度为0且不包含根节点的缩点个数即为答案。易证,入度不为0的缩点一定可以通过与它连接的缩点到达(s)节点。

    AC题解

    #include<bits/stdc++.h>
    using namespace std;
    const int N=5010;
    int fst[N],nxt[N],v[N],cnt;
    int c[N],dfn[N],low[N],pos,sum,s;//c[i]:编号为i的节点所在强连通分量编号
    bool ins[N],in[N];//in[i]:编号为i的强连通分量是(1)否(0)有入边
    stack<int> st; 
    void add(int a,int b)
    {
    	v[++cnt]=b;
    	nxt[cnt]=fst[a]; fst[a]=cnt;
    }
    void tarjan(int x)
    {
    	dfn[x]=low[x]=++pos;
    	st.push(x); ins[x]=1;
    	for(int i=fst[x];i;i=nxt[i])
    	{
    		int y=v[i];
    		if(!dfn[y]) {tarjan(y); low[x]=min(low[x],low[y]);}
    		else if(ins[y]) low[x]=min(low[x],dfn[y]);
    	}
    	if(dfn[x]==low[x])
    	{
    		c[x]=++sum; ins[x]=0;
    		while(st.top()!=x) 
    		{
    			int t=st.top(); st.pop();
    			c[t]=sum; ins[t]=0;
    		}
    		st.pop();
    	}
    }
    int main()
    {
    	int n,m,ans=0;
    	scanf("%d%d%d",&n,&m,&s);
    	int x,y;
    	for(int i=1;i<=m;i++) {scanf("%d%d",&x,&y); add(x,y);}
        //tarjan缩点
    	for(int i=1;i<=n;i++)
    		if(!dfn[i]) tarjan(i);
        //统计入度
    	for(int i=1;i<=n;i++)
    		for(int j=fst[i];j;j=nxt[j])
    			if(c[v[j]]!=c[i]) in[c[v[j]]]=1;
    	in[c[s]]=1;//不可以计算包含根节点的强连通分量
        //统计答案
    	for(int i=1;i<=sum;i++) ans+=(in[i]^1);
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    linux软件安装
    shell脚本
    ssh密钥登录及远程执行命令
    shell编程
    vi编辑器
    linux入门
    《玩转Bootstrap(JS插件篇)》笔记
    SharePoint BI
    Apache-ActiveMQ transport XmlMessage
    C#操作AD及Exchange Server总结(二)
  • 原文地址:https://www.cnblogs.com/violetholmes/p/14227283.html
Copyright © 2011-2022 走看看