有向图强连通分量-poj-2186-Popular Cows
来源:互联网 发布:网络存储软件有哪些 编辑:程序博客网 时间:2024/05/20 05:58
题意:有些牛有自己的偶像,偶像的偶像也是自己的偶像,问存在多少牛被所有牛崇拜。
题解:牛a崇拜牛b就连一条a指向b的边,然后找出所有的强连通分量(即这个分量里的每个点都可以到达分量中的任意一个点)。判断有没有出度为0的强连通分量,而且这个点只有一个,如果有,那么答案就是这个强连通分量里面点的个数。
顺便可以把这个作为强连通分量的模板。
先放一个tarjan 强连通分量模板
struct recordtime{ int index,low;}tour[SIZE_N];stack<int>sta;int vernum,edgnum,Dindex, scc;int used[SIZE_N],instack[SIZE_N], belong[SIZE_N],num[SIZE_M];void inittarjan(){ Dindex=0; scc=0; memset(used,-1,sizeof(used)); memset(instack,0,sizeof(instack)); memset(belong,0,sizeof(belong)); memset(num,0,sizeof(num));}void tarjan(int x){ int w,u; used[x]=1; tour[x].index=Dindex; tour[x].low=Dindex; Dindex++; sta.push(x); instack[x]=1; for(int an=head[x];an!=-1;an=pra[an].next) { u=pra[an].to; if(used[u]==-1) { tarjan(u); tour[x].low=min(tour[x].low,tour[u].low); } else { //查找栈中的元素 if(instack[u]==1) tour[x].low=min(tour[x].low,tour[u].index); } } if(tour[x].low==tour[x].index) { scc++; do { w=sta.top(); sta.pop(); instack[w]=0; belong[w]=scc; num[scc]++; //printf("%d ",w); }while(w!=x); //printf("\n"); }}
再放一个已经ac的完整代码
#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<stack>#define SIZE_N 10100#define SIZE_M 50100using namespace std;struct peck{ int to,next;}pra[SIZE_M];int e,outnum,ang;int head[SIZE_N],out[SIZE_N];void init(){ e=0; memset(head,-1,sizeof(head)); outnum=0; ang=0; memset(out,0,sizeof(out));}void addedge(int x,int y){ pra[e].to=y; pra[e].next=head[x]; head[x]=e++;}struct recordtime{ int index,low;}tour[SIZE_N];stack<int>sta;int vernum,edgnum,Dindex, scc;int used[SIZE_N],instack[SIZE_N], belong[SIZE_N],num[SIZE_M];void inittarjan(){ Dindex=0; scc=0; memset(used,-1,sizeof(used)); memset(instack,0,sizeof(instack)); memset(belong,0,sizeof(belong)); memset(num,0,sizeof(num));}void tarjan(int x){ int w,u; used[x]=1; tour[x].index=Dindex; tour[x].low=Dindex; Dindex++; sta.push(x); instack[x]=1; for(int an=head[x];an!=-1;an=pra[an].next) { u=pra[an].to; if(used[u]==-1) { tarjan(u); tour[x].low=min(tour[x].low,tour[u].low); } else { //查找栈中的元素 if(instack[u]==1) tour[x].low=min(tour[x].low,tour[u].index); } } if(tour[x].low==tour[x].index) { scc++; do { w=sta.top(); sta.pop(); instack[w]=0; belong[w]=scc; num[scc]++; //printf("%d ",w); }while(w!=x); //printf("\n"); }}void pri(){ for(int i=1;i<=vernum;i++) { printf("the %d th ",i); for(int an=head[i];an!=-1;an=pra[an].next) printf("%d ",pra[an].to); printf("\n"); }}int main(){ int compact,burgeon; //存图 while(scanf("%d %d",&vernum,&edgnum)!=EOF) { init(); inittarjan(); for (int i = 1;i<=edgnum;i++) { scanf("%d %d",&compact,&burgeon); addedge(compact,burgeon); } //pri(); for (int i = 1;i<=vernum;i++) { if(used[i]==-1) tarjan(i); } for (int i = 1;i<=vernum;i++) { for(int an=head[i];an!=-1;an=pra[an].next) { int u=pra[an].to; int verbe=belong[i]; int tobe=belong[u]; if(verbe!=tobe){ out[verbe]=1;//出度不为0 //printf("dengyuyi%d\n",u); } } } for (int i = 1;i<=scc;i++)//这里i是<=强连通分量的组数 { //printf("out[%d]=%d\n",i,out[i]); if(out[i]==0) { outnum++; ang=i; }//printf("%d\n",ang); } if(outnum!=1)//如果出度不为0的强连通分量有两个 那说明并不是被所有牛崇拜 num[ang]=0; printf("%d\n",num[ang]); } return 0;}
0 0
- 有向图强连通分量-poj-2186-Popular Cows
- poj 2186 Popular Cows 有向图强连通分量 tarjan
- 求解有向图的强连通分量的SCC问题---POJ 2186 Popular Cows
- poj2186 Popular Cows 有向图 强连通分量
- POJ 2186-Popular Cows ---强连通分量
- POJ 2186 Popular Cows / 强连通分量
- POJ 2186 Popular Cows 强连通分量
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows 强连通分量
- POJ 2186 Popular Cows 强连通分量
- poj 2186 Popular Cows 强连通分量
- POJ 2186 Popular Cows(强连通分量)
- poj 2186 Popular Cows 【强连通分量】
- |poj 2186|强连通分量|Popular Cows
- poj 2186 Popular Cows 强连通分量
- POJ 2186 Popular Cows (强连通分量)
- 搞IT,算法编程不错的学习网址 & 一些专栏博客大神的地址(汇总)
- 数据类型之间的转换
- hdu 1066 数论+递归
- NOJ J题 FootBall
- bat脚本编译单片机程序
- 有向图强连通分量-poj-2186-Popular Cows
- CSS3自定义美化复选框Checkbox组合
- Loadrunner Log Message 打印参数
- 自动人脸识别技术【挑战性问题】
- Direct-Load-apk启动插件的原理
- Spring Security身份认证之HelloSpringSecurity
- 理解GBDT算法(二)——基于残差的版本
- poj1011 搜索
- UVa #12661 Funny Car Racing (例题11-11)