LOJ-10091(强连通分量)

题目链接:传送门

思路:

多少头牛收到所有牛头牛的喜欢,喜欢具有传递性,所以将互相喜欢的牛视为一个点,就是有向图的

缩点,收到所有牛的喜欢要求这个“点”没有出度,所以缩点之后统计所有没有出度的点就是结果,如果有多头牛没有出度,

就说明图不连通,答案为0。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = ;
int num[maxn],low[maxn],vis[maxn],head[maxn],ver[maxn],next[maxn],tot;
int st[maxn],out[maxn],fa[maxn],top,tim,col;
int MIN(int x,int y)
{
return x<y?x:y;
}
int MAX(int x,int y)
{
return x>y?x:y;
}
void Init()
{
memset(vis,,sizeof(vis));
memset(low,,sizeof(low));
memset(num,,sizeof(num));
memset(head,,sizeof(head));
memset(ver,,sizeof(ver));
memset(next,,sizeof(next));
memset(st,,sizeof(st));
memset(out,,sizeof(out));
memset(fa,,sizeof(fa));
top=;tim=;tot=;col=;
}
void addedge(int u,int v)
{
ver[++tot]=v;next[tot]=head[u];head[u]=tot;
}
void Tarjan(int u) //强连通模板
{
low[u]=num[u]=++tim;
vis[u]=;
st[++top]=u;
for(int i=head[u];i;i=next[i]){
int v=ver[i];
if(!vis[v]){
Tarjan(v);
low[u]=MIN(low[u],low[v]);
}
else if(!fa[v]) low[u]=MIN(low[u],num[v]);
}
if(low[u]==num[u]){
fa[u]=++col;
while(st[top]!=u){
fa[st[top]]=col;
top--;
}
top--;
}
}
int main(void)
{
int n,m,i,j,x,y;
while(~scanf("%d%d",&n,&m)){
Init();
for(i=;i<=m;i++){
scanf("%d%d",&x,&y);
addedge(x,y);
}
for(i=;i<=n;i++)
if(!vis[i]) Tarjan(i); for(i=;i<=n;i++){
for(j=head[i];j;j=next[j]){
if(fa[i]!=fa[ver[j]]) out[fa[i]]++; //统计缩点后每个点的出度
}
}
x=;
int cnt=,sum=;
for(i=;i<=col;i++)
if(out[i]==) cnt++,x=i;
if(cnt==){ //当且仅当只有一个“点”时才有结果
for(i=;i<=n;i++) //统计这个缩点中的点数
if(fa[i]==x) sum++;
printf("%d\n",sum);
}
else printf("0\n");
}
return ;
}
上一篇:fastjson 操作


下一篇:SpringCloud路由网关Zuul