poj2186 Strong connection contraction point

Popular Cows
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 29141   Accepted: 11779

Description

Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is 
popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow. 

Input

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

* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular. 

Output

* Line 1: A single integer that is the number of cows who are considered popular by every other cow. 

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

The meaning of the question: It is required to find the number of points that can be traversed by all points. 
Ideas: The strongly connected component shrinks the point (the ring shrinks point), and turns it into a DAG graph, that is, a tree or a deep forest. Discuss whether there are points with an out-degree of 0, record For the sum of these points, if sum=1, it means that all other points at this point can be traversed. If sum>1, it means that there is no such point in this graph. [(1->2,1->3) In this case or The picture shows the forest]
After finding the point, the algorithm for recording the number of strongly connected shrinking points before the shrinking point
still uses targan, the stack processing is a bit different from the previous judgment shrinking point, the double connected component is different, and the judgment condition is low[u] ==dfn[u]
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>

const int inf = 0x3f3f3f;
const int MAXN = 1e4+10;
const int MMAXN = 5e4+10;
struct edge{
  int st;
  int to;
  int next;
  int vis;
};

using namespace std;
edge e[MMAXN];
stack<int>s;
int first[MAXN];
int dfn[MAXN];
int low[MAXN];
int mark[MAXN];
int out[MAXN];
int top,sum,cur,ans;
int flag;
int n,m;

void init(){
    memset(first,-1,sizeof(first));
    memset(dfn,0,sizeof(dfn));
    memset(low,0,sizeof(low));
    memset(mark,-1,sizeof(mark));
    memset(out,0,sizeof(out));
    top = sum = cur = flag = ans = 0;
}

void addedge(int u,int v){
    e[top].st = u;
    e[top].to = v;
    e [top] .vis = 0 ;
    e[top].next = first[u];
    first[u] = top++;
}

void dfs(int u,int t){
    dfn[u] = low[u] = t;
    int v;
    s.push(u);
    for(int i=first[u];i!=-1;i=e[i].next){
        v = e[i].to;
        if(!dfn[v]){
            dfs(v,t+1);
            low[u] = min(low[u],low[v]);
        }
        else{
            low[u] = min(low[u],dfn[v]);
        }
    }

    if(low[u]==dfn[u]){
        /*cout<<"********"<<endl;
        cout<<u<<endl;
        cout<<"********"<<endl;*/
        while(s.top()!=u){
            mark[s.top()] = cur;
            s.pop();
        }
        mark[s.top()] = cur;
        s.pop();
        cur++;
    }
}

intmain ()
{
   // init();
    int a,b,x;
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        for(int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            addedge(a,b);
        }
        for(int i=1;i<=n;i++){
            if(!dfn[i])
                dfs(i,1);
        }
        /*for(int i=1;i<=n;i++){
            cout<<mark[i]<<" ";
        }
        cout<<endl;*/
        for(int i=1;i<=n;i++){
            for(int j=first[i];j!=-1;j=e[j].next){
                int v = e[j].to;
                if(mark[i]!=mark[v]){
                    out[mark[i]]++;
                }
            }
        }
        /*for(int i=0;i<cur;i++){
            cout<<out[i]<<" ";
        }
        cout<<endl;*/
        for(int i=0;i<cur;i++){
            if(out[i]==0){
                sum++;
                x = i;
            }
        }
        if(sum!=1){
            cout<<0<<endl;
            continue;
        }
        for(int i=1;i<=n;i++){
            if(mark[i]==x)ans++;
        }
        cout<<ans<<endl;
    }
    //cout << "Hello world!" << endl;
    return 0;
}
View Code

 

Reprinted in: https://www.cnblogs.com/EdsonLin/p/5456258.html

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326368078&siteId=291194637