题目大意:
给定一个n个点的有向图( 1<=n<=5000 ),要求你输出所有满足条件的点,条件是点在 出度为0的强连通分量里,点要按标号大小升序输出。
tarjan太强大了,,
Source Code
Problem: 2553
User: 1013101127
Memory: 808K
Time: 266MS
Language: C++
Result: Accepted
Source Code
#include<iostream>
#include<cstdio>
#include <cmath>
#include <vector>
#include <stack>;
#include<cstring>
using namespace std;
const int nMax=5005;
const int mMax=9000005;
int n,m;
vector<int >mp[nMax];
stack<int>mystack;
int dfn[nMax];
int low[nMax];
int vis[nMax];
int tmp;
int belong[nMax];
int cnt;
int out[nMax];
void tarjan(int u)
{
dfn[u]=low[u]=tmp;
tmp++;
vis[u]=1;
mystack.push(u);
for(int i=0;i<mp[u].size();i++)
{
int v=mp[u][i];
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v])
{
low[u]=min(dfn[v],low[u]);
}
}
if(low[u]==dfn[u])
{
++cnt;
int v;
do
{
v=mystack.top();
mystack.pop();
vis[v]=0;
belong[v]=cnt;
}while(v!=u);
}
}
void dfs(int u)
{
vis[u]=1;
for(int i=0;i<mp[u].size();++i)
{
int v= mp[u][i];
if( belong[u] != belong[v] )
out[ belong[u] ]++;
if( !vis[v] )
dfs( v );
}
}
int main()
{
while(cin>>n)
{
if(!n)break;
cin>>m;
int u,v;
tmp=1;
cnt=0;
memset(vis,0,sizeof(vis));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(out,0,sizeof(out));
for(int i=1;i<=n;i++)
mp[i].clear();
while(!mystack.empty())
mystack.pop();
for(int i=0;i<m;i++)
{
cin>>u>>v;
mp[u].push_back(v);
}
for(int i=1;i<=n;i++)
{
if(!dfn[i])
tarjan(i);
}
memset(vis,0,sizeof(vis));
memset(out,0,sizeof(out));
for(int i=1;i<=n;++i)
{
if( !vis[i] )
dfs(i);
}
vector<int>ans;
ans.clear();
for(int i=1;i<=n;++i)
if( out[ belong[i] ] == 0 )
ans.push_back( i );
for(int i=0;i<ans.size();++i)
printf("%d%c", ans[i], i==ans.size()-1 ? '\n' : ' ' );
}
return 0;
}
题目大意:
给定一个n个点的有向图( 1<=n<=5000 ),要求你输出所有满足条件的点,条件是点在 出度为0的强连通分量里,点要按标号大小升序输出。
tarjan太强大了,,
Source Code
Problem: 2553 | User: 1013101127 | |
Memory: 808K | Time: 266MS | |
Language: C++ | Result: Accepted |
- Source Code
#include<iostream> #include<cstdio> #include <cmath> #include <vector> #include <stack>; #include<cstring> using namespace std; const int nMax=5005; const int mMax=9000005; int n,m; vector<int >mp[nMax]; stack<int>mystack; int dfn[nMax]; int low[nMax]; int vis[nMax]; int tmp; int belong[nMax]; int cnt; int out[nMax]; void tarjan(int u) { dfn[u]=low[u]=tmp; tmp++; vis[u]=1; mystack.push(u); for(int i=0;i<mp[u].size();i++) { int v=mp[u][i]; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(vis[v]) { low[u]=min(dfn[v],low[u]); } } if(low[u]==dfn[u]) { ++cnt; int v; do { v=mystack.top(); mystack.pop(); vis[v]=0; belong[v]=cnt; }while(v!=u); } } void dfs(int u) { vis[u]=1; for(int i=0;i<mp[u].size();++i) { int v= mp[u][i]; if( belong[u] != belong[v] ) out[ belong[u] ]++; if( !vis[v] ) dfs( v ); } } int main() { while(cin>>n) { if(!n)break; cin>>m; int u,v; tmp=1; cnt=0; memset(vis,0,sizeof(vis)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(out,0,sizeof(out)); for(int i=1;i<=n;i++) mp[i].clear(); while(!mystack.empty()) mystack.pop(); for(int i=0;i<m;i++) { cin>>u>>v; mp[u].push_back(v); } for(int i=1;i<=n;i++) { if(!dfn[i]) tarjan(i); } memset(vis,0,sizeof(vis)); memset(out,0,sizeof(out)); for(int i=1;i<=n;++i) { if( !vis[i] ) dfs(i); } vector<int>ans; ans.clear(); for(int i=1;i<=n;++i) if( out[ belong[i] ] == 0 ) ans.push_back( i ); for(int i=0;i<ans.size();++i) printf("%d%c", ans[i], i==ans.size()-1 ? '\n' : ' ' ); } return 0; }