POJ2553

题意:很难懂!但是大体意思就是求有向图中从一个节点出发到达的点也能反向到达该节点的点。如a能到{b1,b2.....bx}这些点,而这些点也能到a,则a为要求的点。题目是求出所有的这种点。

对图进行缩点,缩点后出度为0的点(强连通分量)所包含的点就是答案。原因,自己思考一下.....

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<stack>
  6 #include<vector>
  7 using namespace std;
  8 const int maxn=5010;
  9 const int maxm=500010;
 10 int n,m;
 11 struct edge
 12 {
 13     int u,v,next;
 14 }e[maxm],ee[maxm];
 15 int head[maxn],js,headd[maxn],jss;
 16 int dfsn[maxn],low[maxn],visx,sshu;
 17 int belong[maxn],ss[maxn];
 18 stack<int>st;
 19 bool ins[maxn];
 20 int chudu[maxn];
 21 vector<int>bl[maxn];
 22 vector<int>ans;
 23 void init()
 24 {
 25     memset(head,0,sizeof(head));
 26     memset(e,0,sizeof(e));
 27     js=0;
 28     memset(headd,0,sizeof(headd));
 29     memset(ee,0,sizeof(ee));
 30     jss=0;
 31     memset(dfsn,0,sizeof(dfsn));
 32     memset(low,0,sizeof(low));
 33     visx=sshu=0;
 34     memset(belong,0,sizeof(belong));
 35     memset(ss,0,sizeof(ss));
 36     while(!st.empty())st.pop();
 37     memset(ins,0,sizeof(ins));
 38     memset(chudu,0,sizeof(chudu));
 39     ans.resize(0);
 40     for(int i=0;i<maxn;i++)bl[i].resize(0);
 41 }
 42 void addage(int u,int v,edge e[],int head[],int &js)
 43 {
 44     e[++js].u=u;e[js].v=v;
 45     e[js].next=head[u];head[u]=js;
 46 }
 47 void tarjan(int u)
 48 {
 49     low[u]=dfsn[u]=++visx;
 50     st.push(u);
 51     ins[u]=1;
 52     for(int i=head[u];i;i=e[i].next)
 53     {
 54         int v=e[i].v;
 55         if(dfsn[v]==0)
 56         {
 57             tarjan(v);
 58             low[u]=min(low[u],low[v]);
 59         }
 60         else if(ins[v] && low[u]>dfsn[v]) low[u]=dfsn[v];
 61     }
 62     if(low[u]==dfsn[u])
 63     {
 64         sshu++;
 65         int tp;
 66         do{
 67             tp=st.top();
 68             st.pop();
 69             ins[tp]=0;
 70             bl[sshu].push_back(tp);
 71             belong[tp]=sshu;
 72             ss[sshu]++;
 73         }while(tp!=u);
 74     }
 75 }
 76 void addd(int x)
 77 {
 78     for(int i=0;i<bl[x].size();i++)
 79     {
 80         int y=bl[x][i];
 81         ans.push_back(y);
 82     }
 83 }
 84 
 85 int main()
 86 {
 87     while(scanf("%d%d",&n,&m)==2)
 88     {
 89         init();
 90         for(int u,v,i=0;i<m;i++)
 91         {
 92             scanf("%d%d",&u,&v);
 93             addage(u,v,e,head,js);
 94         }
 95         for(int i=1;i<=n;i++)
 96             if(dfsn[i]==0)tarjan(i);
 97         for(int i=1;i<=m;i++)
 98         {
 99             int u=e[i].u,v=e[i].v;
100             if(belong[u]!=belong[v])
101             {
102                 addage(belong[u],belong[v],ee,headd,jss);
103                 chudu[belong[u]]++;
104             }
105         }
106         for(int i=1;i<=sshu;i++)
107             if(chudu[i]==0)addd(i);
108         sort(ans.begin(),ans.end());
109         for(int i=0;i<ans.size();i++)printf("%d ",ans[i]);
110         printf("
");
111     }
112     
113     return 0;
114 }
View Code
原文地址:https://www.cnblogs.com/gryzy/p/6229804.html