USACO06JAN The Cow Prom /// tarjan求强联通分量 oj24219

题目大意:

n个点 m条边的图 求大小大于1的强联通分量的个数

https://www.cnblogs.com/stxy-ferryman/p/7779347.html

tarjan求完强联通分量并染色后

计算一下每种颜色的个数 就是每个强联通块的大小

#include <stdio.h>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std;

const int N=10005;
struct EDGE { int to, nt; }e[5*N];
int head[N], tot;
int dfn[N], low[N], ind;
int col[N], id;
bool vis[N];
stack <int> s;

int n, m, cnt[N];

void init() {
    while(!s.empty()) s.pop();
    for(int i=0;i<=n;i++) {
        head[i]=dfn[i]=low[i]=col[i]=-1;
        vis[i]=cnt[i]=0;
    }
    tot=ind=id=0;
}
void addE(int u,int v) {
    e[tot].to=v;
    e[tot].nt=head[u];
    head[u]=tot++;
}

void tarjan(int u) {
    dfn[u]=low[u]=ind++;
    s.push(u); vis[u]=1;
    for(int i=head[u];i!=-1;i=e[i].nt) {
        int v=e[i].to;
        if(dfn[v]==-1) {
            tarjan(v);
            low[u]=min(low[u],low[v]);
        } else {
            if(vis[v]) low[u]=min(low[u],low[v]);
        }
    }
    if(dfn[u]==low[u]) {
        col[u]=++id;
        vis[u]=0;
        while(s.top()!=u) {
            col[s.top()]=id;
            vis[s.top()]=0;
            s.pop();
        } s.pop();
    }
}

int main()
{
    while(~scanf("%d%d",&n,&m)) {
        init();
        for(int i=1;i<=m;i++) {
            int u,v;
            scanf("%d%d",&u,&v);
            addE(u,v);
        }
        for(int i=1;i<=n;i++)
            if(dfn[i]==-1) tarjan(i);
        for(int i=1;i<=n;i++)
            cnt[col[i]]++;
        int ans=0;
        for(int i=1;i<=id;i++)
            if(cnt[i]>1) ans++;
        printf("%d\n",ans);
    }

    return 0;
}

原文地址:https://www.cnblogs.com/zquzjx/p/10011297.html

时间: 2024-10-04 12:52:35

USACO06JAN The Cow Prom /// tarjan求强联通分量 oj24219的相关文章

hihoCoder#1185 : 连通性&#183;三 tarjan求强联通分量 缩点 dfs/拓扑排序求路径和最大值

题目链接: http://hihocoder.com/problemset/problem/1185# 题意: n个点,每个点有一个权值,m条有向边,从1出发,每走到一个点, 就吃掉这个点的草,当没有可以到达的草场或是能够到达的草场都已经被吃光了之后就要返回到1了.求最多可以吃掉多少草. 思路: 提示里面讲的挺好的 如果草场是一个强连通图,那么我们只要走到任意一点,就可以把其他所有的草场都走一遍,并且可以选择任意一个点作为终点.所以把强联通块缩成一个点 因为一个强连通块会被缩成一个点,那么我们可

tarjan求强联通分量 模板

1 void tarjan(int u) 2 { 3 dfn[u]=low[u]=++dfs_clock; 4 stack_push(u); 5 6 for (int c=head[u];c;c=nxt[c]) 7 { 8 int v=to[c]; 9 if (!dfn[v]) 10 { 11 tarjan(v); 12 low[u]=min(low[u],low[v]); 13 } 14 else if (!scc[v]) 15 low[u]=min(low[u],dfn[v]); 16 }

tarjan算法求强联通分量

昨天学到了一个新的算法tarjan算法,感觉最近都没有怎么学习了...(最近有个感悟啊,就是学习一定的通过实践来进步的. 现在才明白为什么高中的时候老师强调一定要刷题,当然刷完题目之后的总结也非常地重要! 这个tarjan算法用来求强联通分量,在网上看了几篇blog,然后做了一个题目,感觉这个算法很nice啊... 如果没有学这个算法, 我肯定会想直接dfs吧orz... dfs看看是不是每个点能到达连通分量的其他点,好像这样非常麻烦啊,还要记录这个点从哪里来的...这样一想,好像直接dfs我做

Tarjan的强联通分量

求强联通分量有很多种. <C++信息学奥赛一本通>  中讲过一个dfs求强联通分量的算法Kosdaraju,为了骗字数我就待会简单的说说.然而我们这篇文章的主体是Tarjan,所以我肯定说完之后再赞扬一下Tarjan大法好是不是 首先我们讲一下强联通分量 强联通分量指的是图的一个子图.在这个子图中,任意两个节点都可以互相到达.从定义上我们就可以看出是一个有向图来,因为任意一个无向图都符合该定义. 而它的标准定义是:有向图中任意两点都联通的最大子图. 咳咳,首先庆祝一下哈--本人博客的第一张图.

codevs 2822 爱在心中 tarjan(强联通分量)

2822 爱在心中 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description “每个人都拥有一个梦,即使彼此不相同,能够与你分享,无论失败成功都会感动.爱因为在心中,平凡而不平庸,世界就像迷宫,却又让我们此刻相逢Our Home.” 在爱的国度里有N个人,在他们的心中都有着一个爱的名单,上面记载着他所爱的人(不会出现自爱的情况).爱是具有传递性的,即如果A爱B,B爱C,则A也爱C.如果有这样一部分人,他们彼此都相爱,则他们就超越了一

POJ 3180-The Cow Prom (图论-有向图强联通tarjan算法)

题目大意:有n个牛在一块, m条单项绳子, 有m个链接关系, 问有多少个团体内部任意两头牛可以相互可达 解题思路:有向图强连通分量模版图 代码如下: #include<stdio.h> #include<vector> #include<map> #include<set> #include<algorithm> using namespace std; typedef long long ll; const int N = 10003; vec

POJ-3180 The Cow Prom(tarjan求强连通分量)

题目链接:http://poj.org/problem?id=3180 题目大意:求一个有向图的强连通分量 算法:求强连通分量首选tarjan算法 这里简单说一下tarjan的思路 时间戳是什么:在搜索时访问的最早时间 维护dfn[u]表示u的时间戳 low[u]表示u点所能回到的最早的祖先的时间戳 开一个栈,把搜索的点入栈.搜索时遇到已经搜过的点,取low[u]和dfn[v]的最小值,回溯时取low[u]和low[v]的最小值(标记上传)传到dfn[u]<=low[u]时表示已经回溯到最上面的

Tarjan 算法求强联通分量

转载自:http://blog.csdn.net/xinghongduo/article/details/6195337 还是没懂Tarjan算法的原理.但是感觉.讲的很有道理. 说到以Tarjan命名的算法,我们经常提到的有3个,其中就包括本文所介绍的求强连通分量的Tarjan算法.而提出此算法的普林斯顿大学的Robert E Tarjan教授也是1986年的图灵奖获得者. 首先明确几个概念. 强连通图.在一个强连通图中,任意两个点都通过一定路径互相连通.比如图一是一个强连通图,而图二不是.因

[ACM] HDU 1269 迷宫城堡(Tarjan算法求强联通分量)

迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8099    Accepted Submission(s): 3623 Problem Description 为了训练小希的方向感,Gardon建立了一座大城堡,里面有N个房间(N<=10000)和M条通道(M<=100000),每个通道都是单向的,就是说若称某通道连通了A