首页 > 代码库 > BZOJ 1051: [HAOI2006]受欢迎的牛
BZOJ 1051: [HAOI2006]受欢迎的牛
Description
一个有向图,求所以能被别的点到达的点的个数.
Sol
Tarjan + 强连通分量 + 缩点.
缩点以后找强连通分量,缩点,然后当图有且仅有1个出度为1的点时,有答案.
Code
/************************************************************** Problem: 1051 User: BeiYu Language: C++ Result: Accepted Time:76 ms Memory:3048 kb****************************************************************/ #include<cstdio>#include<stack>#include<vector>#include<iostream>using namespace std; const int N = 10005;#define debug(a) cout<<#a<<"="<<a<<" "#define ct cout<<endl#define _ct cout<<"----------"<<endl int n,m,cnt,bcnt;int dfsn[N],low[N],ins[N],b[N],sz[N];vector<int> g[N];vector<int> h[N];stack<int> stk;struct Edge{ int fr,to; }edge[N*5]; inline int in(int x=0,char ch=getchar()){ while(ch>‘9‘||ch<‘0‘) ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘) x=(x<<3)+(x<<1)+ch-‘0‘,ch=getchar();return x; }void Tarjan(int u,int fa){ dfsn[u]=low[u]=++cnt,ins[u]=1,stk.push(u); for(int i=0,lim=g[u].size(),v;i<lim;i++) if((v=g[u][i])!=fa){ if(!dfsn[v]){ Tarjan(v,u),low[u]=min(low[u],low[v]); } else if(ins[v]) low[u]=min(low[u],dfsn[v]); }if(dfsn[u]==low[u]){ ++bcnt;int v; for(;;){ v=stk.top(),stk.pop(),ins[v]=0,b[v]=bcnt,sz[bcnt]++;if(u==v) break; } }}int main(){// freopen("in.in","r",stdin); n=in(),m=in(); for(int i=1,u,v;i<=m;i++) u=in(),v=in(),g[u].push_back(v),edge[i]=(Edge){ u,v }; for(int i=1;i<=n;i++) if(!dfsn[i]) Tarjan(i,0);// _ct;debug(bcnt),ct; for(int i=1,u,v;i<=m;i++){ u=edge[i].fr,v=edge[i].to;// debug(u),debug(v),ct;// debug(b[u]),debug(b[v]),ct; if(b[u]!=b[v]) h[b[u]].push_back(b[v]); }// _ct; int tmp=0,ans=0; for(int i=1;i<=bcnt;i++){ if(h[i].size()==0) ans=sz[i],tmp++; } if(tmp!=1) putchar(‘0‘);else printf("%d",ans); return 0;}
BZOJ 1051: [HAOI2006]受欢迎的牛
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。