题意:很难懂!但是大体意思就是求有向图中从一个节点出发到达的点也能反向到达该节点的点。如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("\n"); 111 } 112 113 return 0; 114 }
时间: 2024-10-30 23:23:25