标签:
Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 30652 | Accepted: 12439 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
Hint
Source
正向dfs 把顶点标号 反向dfs找出强连通分量。将强连通分量缩点构成DAG。只有一个强连通分量符合条件,只要DAG最后一个强连通分量反向dfs即可,只要全部到达既满足。否则,有多个出度为0的缩点。
#include <cstdio> #include <vector> #include <cstring> #include <algorithm> using namespace std; int n,k; const int maxn=10010; vector<int> g[maxn]; int V;//顶点 vector<int> rg[maxn],vs; bool used[maxn]; int belong[maxn]; void add_edge(int from,int to){ g[from].push_back(to); rg[to].push_back(from); } void dfs(int v){ used[v]=1; for(int i=0;i<g[v].size();i++){ if(!used[g[v][i]]) dfs(g[v][i]); } vs.push_back(v); } void rdfs(int v,int k){ used[v]=1; belong[v]=k; for(int i=0;i<rg[v].size();i++) if(!used[rg[v][i]]) rdfs(rg[v][i],k); } int scc(){ k=0; memset(used,0,sizeof(used)); vs.clear(); for(int v=1;v<=n;v++){ if(!used[v]) dfs(v); } memset(used,0,sizeof(used)); for(int i=vs.size()-1;i>=0;i--) if(!used[vs[i]]) rdfs(vs[i],k++); return k; } int main(){ int m,a,b; //freopen("data.in","r",stdin); while(~scanf("%d%d",&n,&m)){ for(int i=0;i<m;i++){ scanf("%d%d",&a,&b); add_edge(a,b); } int nn= scc(),u=0,num=0; //统计备选解的个数 for(int i=1;i<=n;i++){ if(belong[i]==nn-1){ u=i;num++; } } //检查是否从所有点可达 memset(used,0,sizeof(used)); rdfs(u,0); for(int v=1;v<=n;v++){ if(!used[v]){ num=0;break; } } printf("%d\n",num); } }
标签:
原文地址:http://www.cnblogs.com/acmtime/p/5789742.html