【BZOJ1051】tarjan缩点

题意很好懂的啦

期末月了啦!作业巨多,然后项目还没搞完,哭了。也只能偶尔刷刷题了

分析:
强连通分量经典题

我们直接缩点。
然后呢。
新的图里面如果只有一个入度为0的点,那说明大家都喜欢他啊qwq

然后这题就没了。

#include <bits/stdc++.h>
#define sc(n) scanf("%d",&n)
#define pt(n) printf("%d\n",n)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define vi vector<int>
#define vl vector<long long>
#define pb push_back
using namespace std;
const int maxn = 1e5+7;
vector<int> G[maxn];
int low[maxn],dfn[maxn];
int color[maxn],sum[maxn];
int cnt = 0,col = 0;
stack<int> s;
int ins[maxn];
int deg[maxn];
int n,m;
void tarjan(int x)
{
	low[x] = dfn[x] = ++cnt;
	s.push(x);
	ins[x] = 1;
	for(int i=0;i<G[x].size();i++)
	{
		int v = G[x][i];
		if(!dfn[v])
		{
			tarjan(v);
			low[x] = min(low[x],low[v]); 
		}
		else if(ins[v])
		{
			low[x] = min(low[x],dfn[v]);
		}
	}
	if(low[x]==dfn[x])
	{
		++col;
		while(true)
		{
			int tmp = s.top();
			s.pop();
			sum[color[tmp]=col]++;
			ins[tmp] = 0;
			if(tmp==x) break;
		}
	}
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		G[a].push_back(b);
	}
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i]) tarjan(i);
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<G[i].size();j++)
		{
			int v = G[i][j];
			if(color[i]!=color[v]) deg[color[i]]++;
		}
	}
	int pos = 0,tmp = 0;
	for(int i=1;i<=col;i++)
	{
		if(deg[i]==0)
		{
			pos = i;
			tmp++;
		}
	}
	if(tmp==1) printf("%d\n",sum[pos]);
	else printf("0\n");
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值