您的位置:首页 > 其它

【POJ】3180 - The Cow Prom 强连通分量

2017-09-11 22:00 337 查看
http://poj.org/problem?id=3180

N头牛,M条有向绳子,能组成几个歌舞团?要求顺时针逆时针都能带动舞团内所有牛。

即n个点,m条有向路,能构成几个强连通分量?

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <numeric>
#include <algorithm>
using namespace std;

const int maxn=50005;

int n,m;
vector <int> G[maxn];
vector <int> rG[maxn];
vector <int> vs;
bool vis[maxn];
int cmp[maxn];

void add(int from,int to){
G[from].push_back(to);
rG[to].push_back(from);
}

void dfs(int v){
vis[v]=true;
for (int i=0;i<G[v].size();i++){
if (!vis[G[v][i]]){
dfs(G[v][i]);
}
}
vs.push_back(v);
}

void rdfs(int v,int k){
vis[v]=true;
cmp[v]=k;
for (int i=0;i<rG[v].size();i++){
if (!vis[rG[v][i]]){
rdfs(rG[v][i],k);
}
}
}

int scc(){
memset(vis,false,sizeof(vis));
vs.clear();
for (int i=1;i<=n;i++){
if (!vis[i]){
dfs(i);
}
}
memset(vis,false,sizeof(vis));
int k=0;
for (int i=vs.size()-1;i>=0;i--){
if (!vis[vs[i]]){
rdfs(vs[i],k++);
}
}
return k;
}

int main(){

cin >> n >> m;
for (int i=0;i<m;i++){
int from,to;
scanf("%d%d",&from,&to);
add(from,to);
}

int Scc=scc();
vector <int> cnt(Scc,0);
for (int i=1;i<=n;i++){
cnt[cmp[i]]++;
}

int ans=0;
for (int i=0;i<Scc;i++){
if (cnt[i]>=2){
ans++;
}
}

cout << ans << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: