POJ3180(有向图强连通分量结点数>=2的个数)

The Cow Prom

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 1451   Accepted: 922

Description

The N (2 <= N <= 10,000) cows are so excited: it‘s prom night! They are dressed in their finest gowns, complete with corsages and new shoes. They know that tonight they will each try to perform the Round Dance.

Only cows can perform the Round Dance which requires a set of ropes and a circular stock tank. To begin, the cows line up around a circular stock tank and number themselves in clockwise order consecutively from 1..N. Each cow faces the tank so she can see the other dancers.

They then acquire a total of M (2 <= M <= 50,000) ropes all of which are distributed to the cows who hold them in their hooves. Each cow hopes to be given one or more ropes to hold in both her left and right hooves; some cows might be disappointed.

For the Round Dance to succeed for any given cow (say, Bessie), the ropes that she holds must be configured just right. To know if Bessie‘s dance is successful, one must examine the set of cows holding the other ends of her ropes (if she has any), along with the cows holding the other ends of any ropes they hold, etc. When Bessie dances clockwise around the tank, she must instantly pull all the other cows in her group around clockwise, too. Likewise, 
if she dances the other way, she must instantly pull the entire group counterclockwise (anti-clockwise in British English).

Of course, if the ropes are not properly distributed then a set of cows might not form a proper dance group and thus can not succeed at the Round Dance. One way this happens is when only one rope connects two cows. One cow could pull the other in one direction, but could not pull the other direction (since pushing ropes is well-known to be fruitless). Note that the cows must Dance in lock-step: a dangling cow (perhaps with just one rope) that is eventually pulled along disqualifies a group from properly performing the Round Dance since she is not immediately pulled into lockstep with the rest.

Given the ropes and their distribution to cows, how many groups of cows can properly perform the Round Dance? Note that a set of ropes and cows might wrap many times around the stock tank.

Input

Line 1: Two space-separated integers: N and M

Lines 2..M+1: Each line contains two space-separated integers A and B that describe a rope from cow A to cow B in the clockwise direction.

Output

Line 1: A single line with a single integer that is the number of groups successfully dancing the Round Dance.

Sample Input

5 4
2 4
3 5
1 2
4 1

Sample Output

1

Hint

Explanation of the sample:

ASCII art for Round Dancing is challenging. Nevertheless, here is a representation of the cows around the stock tank:

       _1___
      /****    5 /****** 2
  / /**TANK**|
  \ \********/
   \ \******/  3
    \ 4____/  /
     \_______/

Cows 1, 2, and 4 are properly connected and form a complete Round Dance group. Cows 3 and 5 don‘t have the second rope they‘d need to be able to pull both ways, thus they can not properly perform the Round Dance.

Source

USACO 2006 January Silver

典型的阅读理解题,看了好久的题其实就是求有向图强连通分量结点数>=2的个数。虽然简单,但是第一次确敲错了好几个小地方,敲代码时一定要专心,下面列出错误

/*
ID: LinKArftc
PROG: 3180.cpp
LANG: C++
*/

#include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <utility>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define eps 1e-8
#define randin srand((unsigned int)time(NULL))
#define input freopen("input.txt","r",stdin)
#define debug(s) cout << "s = " << s << endl;
#define outstars cout << "*************" << endl;
const double PI = acos(-1.0);
const double e = exp(1.0);
const int inf = 0x3f3f3f3f;
const int INF = 0x7fffffff;
typedef long long ll;

const int maxn = 10010;
const int maxm = 50010;

struct Edge {
    int v, next;
} edge[maxm];

int head[maxn], tot;

void init() {
    tot = 0;
    memset(head, -1, sizeof(head));
}

void addedge(int u, int v) {
    edge[tot].v = v;
    edge[tot].next = head[u];
    head[u] = tot ++;
}

int n, m;
int dfn[maxn], low[maxn];
bool ins[maxn];
int scc, Time;
stack <int> st;
vector <int> vec[maxn];

void tarjan(int u) {
    int v;
    dfn[u] = low[u] = ++ Time;
    st.push(u);
    ins[u] = true;
    for (int i = head[u]; i + 1; i = edge[i].next) {
        v = edge[i].v;
        if (!dfn[v]) {
            tarjan(v);
            low[u] = min(low[v], low[u]);
        } else if (ins[v]) low[u] = min(low[u], dfn[v]);
    }
    if (dfn[u] == low[u]) {//刚开始写成dfn[u] == low[v]了
        scc ++;
        do {
            v = st.top();
            st.pop();
            ins[v] = false;
            vec[scc].push_back(v);
        } while (u != v);
    }
}

int main() {

    //input;
    int u, v;
    while (~scanf("%d %d", &n, &m)) {
        init();
        for (int i = 1; i <= m; i ++) {//刚开始写成i<=n了
            scanf("%d %d", &u, &v);
            addedge(u, v);
        }
        memset(dfn, 0, sizeof(dfn));
        memset(ins, 0, sizeof(ins));
        while (!st.empty()) st.pop();
        for (int i = 1; i <= n; i ++) vec[i].clear();
        scc = 0;
        Time = 0;
        for (int i = 1; i <= n; i ++) {
            if (!dfn[i]) tarjan(i);
        }
        int ans = 0;
        for (int i = 1; i <= scc; i ++) {
            if (vec[i].size() >= 2) ans ++;
        }
        printf("%d\n", ans);
    }

    return 0;
}
时间: 2024-12-22 06:38:12

POJ3180(有向图强连通分量结点数>=2的个数)的相关文章

有向图强连通分量

部分转自 [有向图强连通分量] 有向图中,如果一个子图内任意两点都可达这这个子图为强连通子图 如图所示{1, 2,3,4},{5},{6} 为一个强连通子图 求连通分量 1.用Kosaraju算法(PS:个人感觉Kosaraju算法比较好理解,但是适用范围不如Tarjan算法广) 如果在原图中点 i 可达 点 j 如果图逆向之后,i 依然可以达到 j ,这么可以认为 i 和 j 在同一个强连通分量里 具体算法是 1.先对图进行一次DFS进行标号确定逆向图进行搜索的次序,越接近图的尾部(搜索树的叶

[图论] 有向图强连通分量 (kosaraju算法,Tarjan算法)

记录自己的想法:在有向图中,如果一些顶点中任意两个顶点都能互相到达(间接或直接),那么这些顶点就构成了一个强连通分量,如果一个顶点没有出度,即它不能到达其他任何顶点,那么该顶点自己就是一个强连通分量.在用kosaraju算法和Tarjan算法求强连通分量的时候,就是给所有的顶点分组染色,同一种颜色的顶点在同一个强连通分量中,记录有多少种颜色(有多少个强联通分量),每个顶点属于哪种颜色(每个顶点在哪个强连通分量重).在同一个强连通分量中的所有顶点可以缩为一个顶点,然后根据缩点构造DAG(有向无环图

【转载】有向图强连通分量的Tarjan算法

from byvoid [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为

算法笔记_144:有向图强连通分量的Tarjan算法(Java)

目录 1 问题描述 2 解决方案 1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.有向图的极大强连通子图,称为强连通分量(strongly connected components). Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量. 定义D

有向图强连通分量的Tarjan算法(转)

原文地址:有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强

有向图强连通分量的Tarjan算法——转自BYVoid

[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为O(N^2+M).更好的

有向图强连通分量的Tarjan算法

有向图强连通分量的Tarjan算法 [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,

【转】有向图强连通分量的Tarjan算法

原文地址:https://www.byvoid.com/blog/scc-tarjan/ [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量

[转]有向图强连通分量的Tarjan算法

[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components). 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达.{5},{6}也分别是两个强连通分量. 直接根据定义,用双向遍历取交集的方法求强连通分量,时间复杂度为O(N^2+M).更好的