标签:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 29141 | Accepted: 11779 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
题意:要求找到所有点都能遍历到的点的个数
思路:强连通分量缩点(环缩点),化成DAG图,也就是树或者深林,讨论有没有出度为0的点,记录这些点的sum,如果sum=1,说明该点所有其他点都能遍历得到,sum>1,说明此图不存在这样的点,【(1->2,1-> 3)这种情况或者图为森林】
找到该点后,记录该点缩点前的个数
强连通缩点的算法依然用targan,栈处理有点和前面的判断缩点,双连通分量不同,判断条件为low[u]==dfn[u]
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <algorithm> #include <string> #include <vector> #include <stack> #include <queue> const int inf = 0x3f3f3f; const int MAXN = 1e4+10; const int MMAXN = 5e4+10; struct edge{ int st; int to; int next; int vis; }; using namespace std; edge e[MMAXN]; stack<int>s; int first[MAXN]; int dfn[MAXN]; int low[MAXN]; int mark[MAXN]; int out[MAXN]; int top,sum,cur,ans; int flag; int n,m; void init(){ memset(first,-1,sizeof(first)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(mark,-1,sizeof(mark)); memset(out,0,sizeof(out)); top = sum = cur = flag = ans = 0; } void addedge(int u,int v){ e[top].st = u; e[top].to = v; e[top].vis = 0; e[top].next = first[u]; first[u] = top++; } void dfs(int u,int t){ dfn[u] = low[u] = t; int v; s.push(u); for(int i=first[u];i!=-1;i=e[i].next){ v = e[i].to; if(!dfn[v]){ dfs(v,t+1); low[u] = min(low[u],low[v]); } else{ low[u] = min(low[u],dfn[v]); } } if(low[u]==dfn[u]){ /*cout<<"********"<<endl; cout<<u<<endl; cout<<"********"<<endl;*/ while(s.top()!=u){ mark[s.top()] = cur; s.pop(); } mark[s.top()] = cur; s.pop(); cur++; } } int main() { // init(); int a,b,x; while(scanf("%d%d",&n,&m)!=EOF){ init(); for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); addedge(a,b); } for(int i=1;i<=n;i++){ if(!dfn[i]) dfs(i,1); } /*for(int i=1;i<=n;i++){ cout<<mark[i]<<" "; } cout<<endl;*/ for(int i=1;i<=n;i++){ for(int j=first[i];j!=-1;j=e[j].next){ int v = e[j].to; if(mark[i]!=mark[v]){ out[mark[i]]++; } } } /*for(int i=0;i<cur;i++){ cout<<out[i]<<" "; } cout<<endl;*/ for(int i=0;i<cur;i++){ if(out[i]==0){ sum++; x = i; } } if(sum!=1){ cout<<0<<endl; continue; } for(int i=1;i<=n;i++){ if(mark[i]==x)ans++; } cout<<ans<<endl; } //cout << "Hello world!" << endl; return 0; }
标签:
原文地址:http://www.cnblogs.com/EdsonLin/p/5456258.html