您的位置:首页 > 其它

poj2186我的第一个强连通题目

2013-11-01 20:43 288 查看
#include <iostream>
#include <cstdio>
#include <cstring>
#include <stack>
#define debug puts("here")

using namespace std;
const int M = 10009;
const int N = 50009;
struct node
{
    int v;
    int next;
}num
;
int sccf[M];
int low[M];
int dfn[M];
bool ins[M];
int adj[M];
int rdu[M];
int scc, index;

stack<int>s;
int n, m;

void init() {

 scc = 0;
 index = 1;
memset(dfn, 0, sizeof(dfn));
memset(low, 0, sizeof(low));
memset(adj, -1, sizeof(adj));
memset(ins, false, sizeof(ins));
memset(sccf, 0, sizeof(sccf));

}

void Tarjan(int u) {

   int v;
   low[u] = dfn[u] = index++;
   s.push(u);
   ins[u] = true;
   for(int k = adj[u]; k != -1; k = num[k].next) {

        v = num[k].v;
        if(dfn[v] == 0) {

            Tarjan(v);
            if(low[v] < low[u]) {

                low[u] = low[v];
            }

        }
        else if(ins[v]&& low[v] < low[u]) {

            low[u] = low[v];
        }
   }
   if(low[u] == dfn[u])
   {
       scc++;
       do
       {
           v = s.top();
           s.pop();
           ins[v] = false;
           sccf[v] = scc;//此步进行所谓的缩点;
       }while(u != v);
   }

}
int getsuperpopularnum() {

  memset(rdu, 0, sizeof(rdu));
  int v, u;
  int cnt = 0;
  int cn
;
  memset(cn, 0, sizeof(cn));
  for(u = 1; u <= n; u++) {

    cn[sccf[u]]++;   //同一缩点内的点数;
    for(int k = adj[u]; k != -1; k = num[k].next)
    {
        v = num[k].v;
        if(sccf[v] != sccf[u])
        {
            rdu[sccf[u]]++;
        }
    }
  }
    for(int i = 1; i <= scc; i++)
    {
        if(rdu[i] == 0)
        {
            cnt++;
            v = i;
        }
    }
    return (cnt == 1)? cn[v] : 0;//如果出度为零的点多以一个, 则无解;
}
int main()
{
   int a, b;
   int e = 0;
   init();
   cin>>n>>m;

   for(int i = 1; i <= m; i++) {

       cin>>a>>b;
       num[e].v = b;  //通过e 找到a 的下一个边b;
       num[e].next = adj[a];//存a可到达的下一个边;
        adj[a] = e;//通过adj[a]找到节点e   
        e++;
   }

   for(int i = 1; i <= n; i++)
   {
       if(dfn[i] == 0)
       {
           Tarjan(i);
       }
   }

  printf("%d\n", getsuperpopularnum());
    return 0;
}
详细资料  :https://www.byvoid.com/blog/scc-tarjan
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐