POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】
来源:互联网 发布:字符串压缩 java 编辑:程序博客网 时间:2024/05/17 05:07
/*Popular Cows ( POJ No.2186)每头牛都想成为牛群中的红人。给定 N 头牛的牛群和 M 个有序对(A, B)。 (A, B)表示牛 A 认为牛 B 是红人。该关系具有传递性,所以如果牛 A 认为牛 B 是红人,牛 B 认为牛 C 是红人,那么牛 A 也认为牛 C 是红人。不过,给定的有序对中可能包含(A, B)和(B, C),但不包含(A, C)。求被其他所有牛认为是红人的牛的总数。限制条件 1 ≤ N ≤ 10000 1 ≤ M ≤ 50000 1 ≤ A, B ≤ N Sample Input3 31 22 12 3Sample Output1次题为典型的求强连通分量的题目,将强连通分量缩点并得到DAG,求的出度为0的强连通分量的点的个数就是答案*/
//Kosaraju算法,异常巧妙#include<cstdio>#include<iostream>#include<cstring>using namespace std;const int maxn=10000+10,maxm=50000+10;int n,m,scc;int stack[maxn],top;int head1[maxn],head2[maxn];struct node{int to,next;};node edge1[maxm],edge2[maxm];//正向边与反向边bool vis[maxn];int num[maxn];//强连通分量点个数 void dfs1(int u){int v;for(int i=head1[u];i!=-1;i=edge1[i].next){v=edge1[i].to;if(!vis[v]){vis[v]=1;dfs1(v);}}stack[top++]=u;}void dfs2(int u){int v;num[scc]++;for(int i=head2[u];i!=-1;i=edge2[i].next){v=edge2[i].to;if(!vis[v]){vis[v]=1;dfs2(v);}}}int main(int argc,char* argv[]){int u,v;while(~scanf("%d%d",&n,&m)){//initscc=top=0;memset(head1,-1,sizeof(head1));memset(head2,-1,sizeof(head2));for(int i=0;i<m;i++){scanf("%d%d",&u,&v);edge1[i].to=v;edge1[i].next=head1[u];head1[u]=i;edge2[i].to=u;edge2[i].next=head2[v];head2[v]=i;}memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++)if(!vis[i]){vis[i]=1;dfs1(i);}int root;memset(vis,0,sizeof(vis));for(top--;top>=0;top--)if(!vis[stack[top]]){root=stack[top];scc++;vis[stack[top]]=1;dfs2(stack[top]);}memset(vis,0,sizeof(vis));vis[root]=1;int ans=num[scc];//如果是个连通图,则从根结点可以一次遍历完dfs2(root);for(int i=1;i<=n;i++)if(!vis[i]){ans=0;break;}printf("%d\n",ans);}return 0;}
//tarjan算法求强连通分量,然后求出出度为0的强连通分量的点的个数 #include<cstdio>#include<iostream>#include<cstring>using namespace std;const int maxn=10000+10,maxm=50000+10;int head[maxn];struct node{int to,next;}edge[maxm];int n,m;int num[maxn],scc;//num为强连通中点的个数,sc为强连通分量的个数int dfn[maxn],low[maxn],index;int stack[maxn],top;bool is[maxn];//判断是否在栈中 bool out[maxn];//记录出度 int belong[maxn];//记录点在哪个强连通分量中 void tarjan(int u){int v;dfn[u]=low[u]=++index;stack[top++]=u;is[u]=true;for(int i=head[u];i!=-1;i=edge[i].next){v=edge[i].to;if(!dfn[v]){tarjan(v);if(low[u]>low[v]) low[u]=low[v];}else if(is[v]&&low[u]>dfn[v])low[u]=dfn[v];}if(dfn[u]==low[u]){scc++;do{v=stack[--top];belong[v]=scc;num[scc]++;is[v]=false;}while(u!=v);}}int main(){int u,v;while(~scanf("%d%d",&n,&m)){//initmemset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(num,0,sizeof(num));//memset(belong,0,sizeof(belong));scc=index=top=0;memset(head,-1,sizeof(head));for(int i=0;i<m;i++){//建图 scanf("%d%d",&u,&v);edge[i].next=head[u];head[u]=i;edge[i].to=v;}for(int i=1;i<=n;i++)if(!dfn[i]){tarjan(i);}memset(out,0,sizeof(out));for(int i=1;i<=n;i++)if(!out[belong[i]]){for(int j=head[i];j!=-1;j=edge[j].next){int v=edge[j].to;if(belong[i]!=belong[v]){out[belong[i]]=true;break;}}}int cnt=0,ans;for(int i=1;i<=scc;i++)if(!out[i]){cnt++;ans=num[i];}if(cnt>1) ans=0;printf("%d\n",ans);}return 0;}
还有个Garbow算法也是求强连通分量的
1 0
- POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】+【Garbow】
- POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】
- POJ2186 Popular Cows【Kosaraju】【强连通分量】
- POJ2186 Popular Cows【Tarjan】【强连通分量】
- poj2186 Popular Cows(强连通分量tarjan)
- poj2186 Popular Cows--Kosaraju算法 & 缩点 & 强连通分量
- poj2186 Popular Cows(强连通分量)(korasaju||tarjan模板题)
- POJ 2186 Popular Cows 强连通分量 Kosaraju or tarjan
- POJ2186 Popular Cows 强连通分量
- POJ2186 Popular Cows(强连通分量)
- POJ2186 Popular Cows 强连通分量
- POJ2186 Popular Cows 【图论】【强连通分量】
- poj2186 Popular Cows(强连通分量)
- POJ2186 Popular Cows 强连通 Tarjan
- poj 2186 Popular Cows(强连通分量,tarjan或Kosaraju)
- poj2186 Popular Cows 有向图 强连通分量
- 图论:POJ2186-Popular Cows (求强连通分量)
- poj 2186 Popular Cows 强联通分量tarjan/Kosaraju
- TabLayout实现底部导航栏
- win10移动 文档 下载 等到其他磁盘
- 批量更改文件编码格式(引入项目中文乱码)
- 注册表及其CRegKey类
- [编程题]字符串最后一个单词的长度
- POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】
- jz2440一些接口注意事项
- linux内存管理基本概念
- Web Service系列之实例之使用http.client发送SOAP POST请求
- Jquery中的offset()和position()的区别
- Java基础学习笔记:(十)static关键字
- mybatis总结(4)---Mybatis 开发DAO两种方法
- JAVA界面 Swing
- 人才推荐系统API接口文档