poj2186 - tarjan + condensing point

Subject to the effect:

      Each cow desire is to become one of the most popular cattle. There are N cows, to give you an integer M (A, B), B represents a cow A cow considered popular. This
Kind of relationship is transitive, if B believes A popular, popular B think C, then A cow cow C also believes that popular. Your task is to find how many heads there
All cattle cattle were considered to be popular.
 
      First with tarjan each strongly connected component is obtained, and then shrink point, the count of each point, and if there is only one of a 0 degree point, it outputs this point contains nodes, otherwise, outputs 0.
 
prove:
      If strongly connected components are isolated (i.e., infinity, and other strongly connected components connected), then the answer must be 0, since this time is a point after the DAG reduction, the degree of point number 1 must be greater than zero.
      If no points are isolated, when the degree is a point when more than 0, by the nature of the DAG is available, there is not a certain point of arrival from all other points. Only when the number of points is equal to 0 to 1, that is the point of arrival is 0 to all other points.
 
#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(~ years) years = sz [years];
    else years = 0 ; 
    printf ( " % d \ n " , year);
    return  0 ; 
}
View Code

 

Guess you like

Origin www.cnblogs.com/DWVictor/p/11332838.html