tarjan模板

  1. tarjan割点
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int low[N],n,m,r,c;
    int dfn[N],p,f[N];
    vector<int>g[N];
    void dfs(int x)
    {
    	p++;
    	dfn[x]=p;
    	low[x]=p;
    	int s=0;
    	for(auto k:g[x])
    	{
    		if(!dfn[k])
    		{
    			s++;
    			dfs(k);
    			low[x]=min(low[x],low[k]);
    			if(low[k]>=dfn[x]&&x!=r)
    			{
    				c+=!f[x];
    				f[x]=1;
    			}
    		}
    		else
    		{
    			low[x]=min(low[x],dfn[k]);
    		}
    	}
    	if(s>=2&&x==r)
    	{
    		c+=!f[x];
    		f[x]=1;
    	}
    }
    int main()
    {
    	cin>>n>>m;
    	while(m--)
    	{
    		int u,v;
    		cin>>u>>v;
    		g[u].push_back(v);
    		g[v].push_back(u);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		if(!dfn[i])
    		{
    			r=i;
    			dfs(i);
    		}
    	}
    	cout<<c<<"\n";
    	for(int i=1;i<=n;i++)
    	{
    		if(f[i])
    		{
    			cout<<i<<" ";
    		}
    	}
    	return 0;
    }

  2. tarjan割边
    #include <bits/stdc++.h>
    using namespace std;
    const int N=6e5+10;
    int h[N],u[N],v[N];
    int n,m,c,p,f[N],k;
    int dfn[N],low[N];
    void add(int x, int y)
    {
    	c++;
    	u[c]=y;
    	v[c]=h[x];
    	h[x]=c;
    }
    void dfs(int x,int k)
    {
    	p++;
    	dfn[x]=p;
    	low[x]=p;
    	for(int i=h[x];i;i=v[i])
    	{
    		int y=u[i];
    		if(!dfn[y])
    		{
    			dfs(y,i);
    			low[x]=min(low[x],low[y]);
    			if(low[y]>dfn[x])
    			{
    				f[i]=1;
    				f[i^1]=1;
    			}
    		}
    		else if(i!=(k^1))
    		{
    			low[x]=min(low[x],dfn[y]);
    		}
    	}
    }
    int main()
    {
    	cin>>n>>m;
    	c=1;
    	for(int i=1;i<=m;i++)
    	{
    		int x,y;
    		cin>>x>>y;
    		add(x,y);
    		add(y,x);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		if(!dfn[i])
    		{
    			dfs(i,0);
    		}
    	}
    	for(int i=2;i<c;i+=2)
    	{
    		k+=f[i];
    	}
    	cout<<k;
    	return 0;
    }

  3. tarjan缩点
    #include <bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int k,dfn[N],low[N];
    int tot,c[N],s[N],f[N];
    int st[N],top,ans,b[N];
    int n,m,a[N],x[N],y[N];
    vector<int>g[N];
    void tarjan(int x)
    {
    	top++;
    	st[top]=x;
    	b[x]=1;
    	k++;
    	dfn[x]=k;
    	low[x]=k;
    	for(auto y:g[x])
    	{
    		if(!dfn[y])
    		{
    			tarjan(y);
    			low[x]=min(low[x],low[y]);
    		}
    		else if(b[y])
    		{
    			low[x]=min(low[x],dfn[y]);
    		}
    	}
    	if(dfn[x]==low[x])
    	{
    		tot++;
    		while(st[top+1]!=x)
    		{
    			c[st[top]]=tot;
    			s[tot]+=a[st[top]];
    			b[st[top]]=0;
    			top--;
    		}
    	}
    }
    void dfs(int x)
    {
    	if(f[x])
    	{
    		return;
    	}
    	f[x]=s[x];
    	int mx=0;
    	for(auto y:g[x])
    	{
    		if(!f[y])
    		{
    			dfs(y);
    		}
    		mx=max(mx,f[y]);
    	}
    	f[x]+=mx;
    }
    int main()
    {
    	cin>>n>>m;
    	for(int i=1;i<=n;i++)
    	{
    		cin>>a[i];
    	}
    	for(int i=1;i<=m;i++)
    	{
    		cin>>x[i]>>y[i];
    		g[x[i]].push_back(y[i]);
    	}
    	for(int i=1;i<=n;i++)
    	{
    		if(!dfn[i])
    		{
    			tarjan(i);
    		}
    	}
    	for(int i=1;i<=n;i++)
    	{
    		g[i].clear();
    	}
    	for(int i=1;i<=m;i++)
    	{
    		if(c[x[i]]!=c[y[i]])
    		{
    			g[c[x[i]]].push_back(c[y[i]]);
    		}
    	}
    	for(int i=1;i<=tot;i++)
    	{  
    		if(!f[i])
    		{
    			dfs(i);
    			ans=max(ans,f[i]);
    		}
    	}
    	cout<<ans;
    	return 0;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值