标签:acm c++ codeforces dfs 图论
题目链接:http://codeforces.com/contest/505/problem/D
#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
using namespace std;
#define N 100010
vector<int> g[N];
vector<int> rg[N];
vector<int> vs;
bool used[N];
int cmp[N];
int n,m;
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;
cmp[v]=k;
for(int i=0;i<rg[v].size();i++)
if(!used[rg[v][i]])
rdfs(rg[v][i],k);
}
int scc()
{
memset(used,0,sizeof(used));
vs.clear();
for(int v=0;v<n;v++)
if(!used[v])
dfs(v);
memset(used,0,sizeof(used));
int k=0;
for(int i=vs.size()-1;i>=0;i--)
if(!used[vs[i]])
rdfs(vs[i],k++);
return k;
}
int cmpsize[N];
bool dfs2(int v)
{
used[v]=1;
bool ans=(cmpsize[cmp[v]]==1);
for(int i=0;i<g[v].size();i++)
{
if(!used[g[v][i]]) ans &= (dfs2(g[v][i])==1);
}
for(int i=0;i<rg[v].size();i++)
{
if(!used[rg[v][i]]) ans &= (dfs2(rg[v][i])==1);
}
return ans;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
memset(cmpsize,0,sizeof(cmpsize));
for(int i=0;i<n;i++)
rg[i].clear(),g[i].clear();
for(int i=0;i<m;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add_edge(u-1,v-1);
}
scc();
memset(used,0,sizeof(used));
for(int i=0;i<n;i++)
cmpsize[cmp[i]]++;
int ans=n;
for(int i=0;i<n;i++)
{
if(!used[i])
ans -= dfs2(i);
}
cout<<ans<<endl;
}
return 0;
}
Codeforces Round #286 div.2 D 505D. Mr. Kitayuta's Technology【强连通分量,弱联通分量】
标签:acm c++ codeforces dfs 图论
原文地址:http://blog.csdn.net/u013912596/article/details/43233039