首页 > 其他 > 详细

bzoj 1051

时间:2017-10-12 20:11:01      阅读:257      评论:0      收藏:0      [点我收藏+]

如果A认为B是受欢迎的,B认为C是受欢迎的,C认为A是受欢迎的,这时形成了一个环。

这时如果A认为D是受欢迎的,那么B和C也认为D是受欢迎的。

于是要考虑缩点。为了好打邻接表用了vector代替。推荐用Tarjan或者Gabow算法。

缩点完最终只有可能有一个强连通分量的牛被全部牛认为是受欢迎的,或者直接没有。

如果有超过一个的强连通分量的出度为0那么没有牛被全部牛认为是受欢迎的。

否则就直接输出那个出度为0的强连通分量中牛的个数。

#include<cstdio>
#include<cctype>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=10001;
const int maxm=50001;
int read(){
    char c; while(!isdigit(c=getchar())); int x=c-0;
    while(isdigit(c=getchar())) x=x*10+c-0; return x;
}
vector<int> e[maxn];
int top,cnt,tme,vis[maxn],low[maxn],dfn[maxn],sta[maxn],num[maxn],dis[maxn],peo[maxn];
void tarjan(int o){
    low[o]=vis[sta[++top]=o]=++tme;
    for(int i=0;i<e[o].size();i+=1)
        if(!dfn[e[o][i]]){
            if(!vis[e[o][i]]) tarjan(e[o][i]);
            low[o]=min(low[e[o][i]],low[o]);
        }
    if(vis[o]==low[o]){
        ++cnt;
        while(dfn[sta[top]]=cnt,peo[cnt]+=1,sta[top--]!=o);
    }
}
int main(){
    int n=read(),m=read(),ans=0;
    while(m--){
        int a=read(),b=read();
        e[a].push_back(b);
    }
    for(int i=1;i<=n;i+=1) if(!dfn[i]) tarjan(i);
    int tot=0,pre=0;
    for(int i=1;i<=n;i+=1)
        for(int j=0;j<e[i].size();j+=1)
            if(dfn[i]!=dfn[e[i][j]]) dis[dfn[i]]=1;
    for(int i=1;i<=cnt;i+=1) if(!dis[i]) tot+=1,pre=i;
    if(tot==1) printf("%d",peo[pre]); else printf("0");
    return 0;
}

 

bzoj 1051

原文:http://www.cnblogs.com/AmnesiacVisitor/p/7657623.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!