POJ 2553 —— The Bottom of a Graph

来源:互联网 发布:厦门拓羽网络 编辑:程序博客网 时间:2024/06/07 14:49

原题:http://poj.org/problem?id=2553


题意:给出n个点,m条边的有向图;问有多少个点 v 满足—— v能到u,u也能到v(v能到达的所有点都要能回到v);

思路:出度 = 0 的强连通分量里的点都满足该情况;


#include<cstdio>  #include<string>  #include<cstring>  #include<queue>#include<vector>  #include<algorithm>  #define inf 0x3f3f3f3f  using namespace std;  const int maxn = 5005;    int n, m;  int DFN[maxn], Low[maxn], Stack[maxn], Belong[maxn];  bool Instack[maxn];  int Time, taj, top;  int head[maxn], edgenum;    struct Edge  {      int from, to, next;  }edge[maxn*maxn]; vector<int>bcc[maxn];void tarjan(int u, int fa){        DFN[u] = Low[u] = ++Time;        Stack[top++] = u;        Instack[u] = true;         for(int i = head[u];i != -1;i = edge[i].next){            int v = edge[i].to ;            if(DFN[v] == -1)          {                tarjan(v, u) ;                Low[u] = min(Low[u], Low[v]);           }            else if(Instack[v] && Low[u] > DFN[v]) Low[u] = DFN[v];            }        if(Low[u] == DFN[u]){             taj++; bcc[taj].clear();          while(1){              int now = Stack[--top];                Instack[now] = false;               Belong[now] = taj;              bcc[taj].push_back(now);              if(now == u)break;        }    }  }    void tarjan_init(int all){      memset(DFN, -1, sizeof DFN);      memset(Instack, false, sizeof Instack);      top = Time = taj = 0;      for(int i = 1;i<=all;i++)    {    if(DFN[i] == -1)tarjan(i, i);}}void add(int u, int v)  {      edge[edgenum].from = u;      edge[edgenum].to = v;      edge[edgenum].next = head[u];      head[u] = edgenum++;  }vector<int>G[maxn];int du[maxn];void suodian(){for(int i = 1;i<=taj;i++)G[i].clear();memset(du, 0, sizeof du);for(int i = 0;i<edgenum;i++){          int u = Belong[edge[i].from];int v = Belong[edge[i].to];          if(u != v){G[u].push_back(v);du[u]++;}     }}void init(){memset(head, -1, sizeof head);edgenum = 0;}int main(){while(~scanf("%d", &n) && n){scanf("%d", &m);init();while(m--){int u, v;scanf("%d%d", &u, &v);add(u, v);}tarjan_init(n);suodian();int ans[maxn];int cnt = 0;for(int i = 1;i<=taj;i++){if(du[i] == 0){for(int j = 0;j<(int)bcc[i].size();j++){int x = bcc[i][j];ans[cnt++] = x;}}}sort(ans, ans+cnt);for(int i = 0;i<cnt;i++){if(i == cnt-1)printf("%d\n", ans[i]);elseprintf("%d ", ans[i]);}}return 0;}


0 0
原创粉丝点击