POJ2186 POPULAR COW

链接:http://poj.org/problem?id=2186

题意:给你N个点,然后在给你N条有向边,然后让你找出这样的点S,S满足条件图上任意一点都能到达S。

要想满足任意一点都能到达,首先满足图连通,然后满足将图缩点后形成一个棵树,树的特征是可以有且只有一个点的出度为0。

然后代码如下:

  1 #include <iostream>
  2 #include <vector>
  3 #include <queue>
  4 #include <string.h>
  5 #include <stdlib.h>
  6 #include <stdio.h>
  7 #include <stack>
  8 
  9 using namespace std;
 10 const int maxn = 50050;
 11 
 12 struct edge
 13 {
 14     int u,v,val;
 15 };
 16 int dfn[10050],low[10050],belong[10050],inst[10050];
 17 vector<edge> edges;
 18 vector<int>g[maxn];
 19 stack<int>st;
 20 int bcnt,cnt,time;
 21 
 22 void init(int n)
 23 {
 24     int i;
 25     for(i =0;i <= n;i++)
 26     g[i].clear();
 27 
 28     edges.clear();
 29     time = 0;bcnt = cnt = 0;
 30     return ;
 31 }
 32 void addedge(int u,int v,int val)
 33 {
 34     edges.push_back((edge){u,v,1});
 35     g[u].push_back(cnt);
 36     cnt++;
 37 
 38     return ;
 39 }
 40 void tarjan(int i)
 41 {
 42     int j;
 43     dfn[i] = low[i] = ++time;
 44     inst[i] = 1;
 45     st.push(i);
 46 
 47     for(j = 0;j < g[i].size();j++)
 48     {
 49         edge e;
 50         e = edges[g[i][j]];
 51         int v;
 52         v = e.v;
 53         if(!dfn[v])
 54         {
 55             tarjan(v);
 56             low[i] = min(low[i],low[v]);
 57         }
 58         else if(inst[v] && dfn[v] < low[i])
 59         low[i] = dfn[v];
 60     }
 61     if(dfn[i] == low[i])
 62     {
 63         //cout<<i<<"****"<<endl;
 64         bcnt++;
 65         do
 66         {
 67             j = st.top();
 68             st.pop();
 69             inst[j] = 0;
 70             belong[j] = bcnt;
 71             //printf("%d *",j);
 72         }
 73         while(j != i);
 74         //puts("");
 75     }
 76 
 77 }
 78 void tarjans(int n)
 79 {
 80     int i;
 81     bcnt = time = 0;
 82     while(!st.empty())st.pop();
 83     memset(dfn,0,sizeof(dfn));
 84 
 85     memset(inst,0,sizeof(inst));
 86     memset(belong,0,sizeof(belong));
 87     for(i = 1;i <= n;i++)
 88     if(!dfn[i])tarjan(i);
 89 }
 90 int main()
 91 {
 92     int n,m;
 93     //freopen("in.txt","r",stdin);
 94     while(~scanf("%d %d",&n,&m))
 95     {
 96         int a,b,i;
 97         init(n);
 98         for(i = 0;i < m;i++)
 99         {
100             scanf("%d %d",&a,&b);
101             addedge(a,b,1);
102 
103 
104         }
105         tarjans(n);
106         //cout<<bcnt<<endl;
107         int leap = 0,flag = 0;
108         int bcnt0,j;
109         int outbc[10050];
110         memset(outbc,0,sizeof(outbc));
111         for(i = 1;i <= n;i++)
112         {
113             for(j = 0;j < g[i].size();j++)
114             {
115                 int v;
116                 v = edges[g[i][j]].v;
117                 if(belong[i] != belong[v]){
118                 if(outbc[belong[i]] == 0)
119                 leap++;
120                 outbc[belong[i]] = 1;
121                 }
122             }
123         }
124         if(leap == bcnt-1)
125         {
126             int ans;
127             ans = 0;
128             for(i = 1;i < bcnt+1;i++)
129             {
130                 if(outbc[i] == 0)
131                 break;
132             }
133             for(j = 1;j <= n;j++)
134             if(belong[j] == i)
135                 ans++;
136 
137             printf("%d
",ans);
138         }
139         else
140         puts("0");
141 
142 
143     }
144     return 0;
145 }
View Code
原文地址:https://www.cnblogs.com/0803yijia/p/3223994.html