您的位置:首页 > 运维架构

poj2186 Popular Cows (强联通分量+缩点)

2016-08-18 17:46 411 查看
Popular Cows

Time Limit: 2000MSMemory Limit: 65536K
Total Submissions: 30641Accepted: 12432
DescriptionEvery cow’s dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is

popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.

Input* Line 1: Two space-separated integers, N and M

* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.

Output* Line 1: A single integer that is the number of cows who are considered popular by every other cow.

Sample Input3 3
1 2
2 1
2 3
Sample Output1
HintCow 3 is the only cow of high popularity.

这道题使用的tarjan求强联通分量。

求出来之后我们可以缩点,就变成了一棵树,然后,我们要求的数量就是叶子节点的大小(因为这个叶子节点是缩点形成的,所以会有大小)。

当然,如果有多个叶子节点,那是不行的,那其中的任一叶子节点肯定不会被其他叶子节点的的牛所崇拜。

如果只有一个强联通分量,那肯定所有的都符合题意,直接特判就是了。

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

const int maxn=1e4+5;
const int maxm=5e4+5;

int n,m;
int head[maxn];
struct note{
int to,next;
}edge[maxm];
int top,dfs_clock,scc_num;

int pre[maxn],low[maxn],inscc[maxn],outdeg[maxn];
stack<int> S;

inline void ADD(int u,int v){
edge[top].to=v;
edge[top].next=head[u];
head[u]=top++;
}

void tarjan(int now){
pre[now]=low[now]=++dfs_clock;
S.push(now);
for(int i=head[now];~i;i=edge[i].next){
int to=edge[i].to;
if(!pre[to]){
tarjan(to);
low[now]=min(low[now],low[to]);
}else if(!inscc[to]){
low[now]=min(low[now],pre[to]);
}
}
if(low[now]==pre[now]){
++scc_num;
while(1){
int x=S.top();S.pop();
inscc[x]=scc_num;
if(x==now)break;
}
}
}

void SCC(){
dfs_clock=scc_num=0;
memset(pre,0,sizeof(pre)),memset(low,0,sizeof(low)),memset(inscc,0,sizeof(inscc));
while(!S.empty()){
S.pop();
}
for(int i=1;i<=n;++i){
if(!pre[i]){
tarjan(i);
}
}
}

int main(){
while(~scanf("%d%d",&n,&m)){
top=0,memset(head,-1,sizeof(head));
for(int i=0;i<m;++i){
int u,v;
scanf("%d%d",&u,&v);
ADD(u,v);
}
SCC();
if(scc_num==1){
printf("%d\n",n);
}else{
memset(outdeg,0,sizeof(outdeg));
for(int i=1;i<=n;++i){
for(int j=head[i];~j;j=edge[j].next){
int to=edge[j].to;
if(inscc[i]^inscc[to]){
++outdeg[inscc[i]];
}
}
}
int J=0,res;
for(int i=1;i<=scc_num;++i){
if(!outdeg[i]){
++J,res=i;
}
}
if(J==1){
int ans=0;
for(int i=1;i<=n;++i){
if(res==inscc[i]){
++ans;
}
}
printf("%d\n",ans);
}else{
printf("0\n");
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: