[强连通分量]poj2186_Popular Cows

来源:互联网 发布:淘宝店铺怎么开通 编辑:程序博客网 时间:2024/05/17 09:32

                                                   这是我做的第一道强连通分量,当然是找模板题来做。。。

此题大致意思就是:

      现在告诉你一些关系,这些关系的形式是A B,表示A牛认为B牛受欢迎,如果A牛认为B牛受欢迎,B牛认为C牛受欢迎,那么A牛也会认为C牛受欢迎,现在问你有多少牛是其他所有牛都认为受欢迎的。

解题思路:

       强连通分量的模板题。。。

       1.首先用强连通分量缩点   

       2.如果缩点之后,只有一个点出度为0,那么这个点中的所有点都是,统计一下答案就行了。每一个强连通分量中的点是可以互相到达的,意思就是说一个强连通分量中的牛互相认为都是受欢迎的,那么如果有一只牛A认为另一头其他强连通分量中的牛B受欢迎,那么根据上面的题意就知道,牛A所在的强连通分量中的所有牛,会认为牛B所在的强连通分量中的所有牛,都是受欢迎的。(自己理解一下应该不难)所以要所有牛都认为你受欢迎,其他所有强连通分量就都会有出边连向其他强连通分量,最后只剩下一个强连通分量是出度为0的,也就是所有牛都认为其都受欢迎。

       3.如果有几个点的出度为0,那么输出0,因为所有牛都还没有关系联系起来,那更别说有所有牛都认为受欢迎的牛。

代码(tarjan算法):

#include<cstdio>#include<iostream>#include<cstdlib>#include<cstring>using namespace std;int du[10010],dfn[10010],low[10010],head[10010];int blong[10010],vis[10010];int sum=0,cnt=0,tot=0,n,m,ti;int stack[10010];struct edgee{int next,to;}edge[100050];void addedge(int u,int v){edge[tot].next=head[u];edge[tot].to=v;head[u]=tot++;}void dfs(int a){dfn[a]=low[a]=++ti;stack[++sum]=a;vis[a]=1;for(int i=head[a];i!=-1;i=edge[i].next) { int b=edge[i].to; if(!vis[b])  {  dfs(b);  low[a]=min(low[a],low[b]); }elseif(vis[b]) low[a]=min(low[a],dfn[b]); }if(dfn[a]==low[a]) { cnt++; int v; do  {  v=stack[sum];  du[v]=cnt;  vis[v]=2;  --sum; }while(v!=a&&sum>0); }}int main(){memset(head,-1,sizeof(head));scanf("%d%d",&n,&m);int x,y;for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); addedge(x,y); }for(int i=1;i<=n;i++) { if(!vis[i]) dfs(i); }for(int i=1;i<=n;i++) {   for(int j=head[i];j!=-1;j=edge[j].next)   if(du[i]!=du[edge[j].to])   blong[du[i]]++; } int ans,pbs=0;for(int i=1;i<=cnt;i++) if(!blong[i])  {  pbs++;  ans=i;  }if(pbs==1) { int Yif=0; for(int i=1;i<=n;i++)  if(du[i]==ans)   Yif++; printf("%d",Yif); }else printf("0");return 0;}

如果有什么问题,欢迎评论。

如果强连通分量不懂,这里有链接(tarjan算法)——https://www.byvoid.com/blog/scc-tarjan/


  


0 0
原创粉丝点击