zoukankan      html  css  js  c++  java
  • 【模板】割点(洛谷P3388)

    Description

      给出一个(n)个点,(m)条边的无向图,求图的割点。

    Input

      第一行输入(n),(m)
      下(m)行每行输入(x),(y)表示(x)(y)有一条边。

    Output

      第一行输出割点个数。
      第二行按照节点编号从小到大输出节点,用空格隔开。

    Solution

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int N=20000,M=200000;
    int n,m,u,v,vis[N+10],cnt,cut[N+10],ans;
    int head[N+10],nxt[M+10],vet[M+10],low[N+10],dfn[N+10];
    inline int read()
    {
    	int ans=0;
    	char ch=getchar();
    	while (ch<'0' || ch>'9') ch=getchar();
    	while (ch>='0' && ch<='9')
    	{
    		ans=ans*10+ch-'0';
    		ch=getchar();
    	}
    	return ans;
    }
    void addedge(int u,int v)
    {
    	nxt[++cnt]=head[u];vet[cnt]=v;head[u]=cnt;
    }
    void tarjan(int u,int rt)
    {
    	vis[u]=1;low[u]=dfn[u]=++cnt;
    	int child=0;
    	for (int i=head[u];i;i=nxt[i])
    	{
    		int v=vet[i];
    		if (!vis[v])
    		{
    			tarjan(v,rt);child++;
    			low[u]=min(low[u],low[v]);
    			if (low[v]>=dfn[u] && u!=rt) ans+=cut[u]?0:1,cut[u]=1;
    			if (child>=2 && u==rt) ans+=cut[u]?0:1,cut[u]=1;
    		}
    		else low[u]=min(low[u],dfn[v]);
    	}
    }
    int main()
    {
    	n=read(),m=read();
    	for (int i=1;i<=m;i++)
    	{
    		int u=read(),v=read();
    		addedge(u,v);
    		addedge(v,u);
    	}
    	for (int i=1;i<=n;i++)
    		if (!vis[i]) tarjan(i,i);
    	printf("%d
    ",ans);
    	for (int i=1;i<=n;i++)
    		if (cut[i]) printf("%d ",i);
    	printf("
    ");
    	return 0;
    }
    
    
  • 相关阅读:
    redhat linux tftp
    mysql
    mysql操作!
    【Android】第一个JNI测试程序
    【android】【google map api v2】google 地图 api v2
    【Android】【转】内存耗用:VSS/RSS/PSS/USS
    【Android】获取Mac地址【2】
    【Android】每个Activity中加入引导界面
    【JNI】javah使用(初步)
    【Android】Eclipse svn插件安装说明
  • 原文地址:https://www.cnblogs.com/Code-Geass/p/9931598.html
Copyright © 2011-2022 走看看