poj2186--tarjan+缩点

Posted dwvictor

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj2186--tarjan+缩点相关的知识,希望对你有一定的参考价值。

题目大意:

      每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
牛被所有的牛认为是受欢迎的。
 
      先用tarjan求出每个强连通分量,再缩点,统计每个点的出度,如果有且只有1个出度为0的点,就输出这个点包含的节点数,否则输出0.
 
证明:
      如果有强连通分量被孤立(即和其他强连通分量无边相连),那么答案一定是0,此时由于缩点后是一个DAG图,出度为0的点的个数一定大于1.
      如果没有点被孤立,当出度为0的点多于1个时,由DAG图的性质可得,一定不存在一个点能从其他所有点到达。只有当出度为0的点的个数等于1时,这个出度为0的点才能被其他所有点到达。
 
技术图片
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
#define cls(s,h) memset(s,h,sizeof s)
const int maxn = 1e5 + 7;
int n , m ;
int tot;
struct  edge

    int to,from,nxt;
e[maxn << 1];

int head[maxn];
void add_edge(int u , int v )
    e[tot].from = u ;
    e[tot].to = v;
    e[tot].nxt = head[u];
    head[u] = tot++;


int stack[maxn << 1],low[maxn << 1],dfn[maxn << 1];
int scc,sz[maxn << 1],c[maxn << 1],st,num;
void init()
    cls(head,-1);
    cls(e,0);
    cls(sz,0);
    scc = 0;
    st = 0;



void tanjan(int u)
    stack[++st] = u;
    dfn[u] = low[u] = ++ num;
    for(int i = head[u],v; ~i ;i = e[i].nxt)
        if(c[v = e[i].to]) continue;
        if(dfn[v]) low[u] = min(low[u],dfn[v]);
        else tanjan(v),low[u] = min(low[u],low[v]);
    
    if(low[u] == dfn[u])
        c[u] = ++ scc; sz[scc] = 1;
        while(st && u != stack[st])
            //SCC number and the scc ge SCC
            c[stack[st--]] = scc,sz[scc] ++;
        st--;
    


int out[maxn << 1];
int main(int argc, char const *argv[])

    init();
    scanf("%d %d",&n,&m);
    for(int i = 1,u,v;i <= m ;i ++)
    scanf("%d %d",&u,&v),add_edge(u,v);
    
    for(int i = 1;i <= n;i ++)
        if(!dfn[i]) tanjan(i);
    for(int i = 0;i < tot;i ++)
        if(c[e[i].from] != c[e[i].to]) out[c[e[i].from]] ++;
    int ans = 0;
    for(int i = 1;i <= scc;i ++)
        if(!out[i]) ans = ans ? -1: i;
    if(~ans) ans = sz[ans];
    else ans = 0;
    printf("%d\n", ans);
    return 0;
View Code

 

以上是关于poj2186--tarjan+缩点的主要内容,如果未能解决你的问题,请参考以下文章

poj2186--tarjan+缩点

poj1236 SCC+缩点

缩点|强连通分量

算法详解之缩点

poj 2186 tarjan求强连通分量

POJ3352(连通分量缩点)