欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

POJ2186-Popular Cows(流行的奶牛)【tarjan,强连通分量,图论】

发布时间:2023/12/3 43 豆豆
生活随笔 收集整理的这篇文章主要介绍了 POJ2186-Popular Cows(流行的奶牛)【tarjan,强连通分量,图论】 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

正题

题目链接


大意

有n头奶牛,奶牛们会认为有些奶牛很受欢迎,受欢迎会互相传递,如:如果A认为B很受欢迎,而B认为C受欢迎,那么A也会认为C是受欢迎的。然后求每一个奶牛都认为受欢迎的奶牛数量。


解题思路

先用tarjan算法算一遍联通分量,然后如果该联通分量出度为0且是唯一一个为0的,那么这个强联通分量里就是受每个奶牛欢迎的。

讲解一下原理:
首先我们假设这道题有解,那么我们将每一个强联通分量看做一个整体,然后如果该整体有出度那么说明这不是最受欢迎的(因为如果受到出度链接的那个整体欢迎的话那么就应该是一个联通分量里的)。如果有两个出度为0那么这两个整体就不会互相喜欢,就无解。


代码

#include<cstdio> #include<stack> using namespace std; stack<int> Stack; struct line{int h,t,next; }; int n,m,dfn[10001],low[10001],stn,ls[10001],ltn,lt[10001]; int ltm[10001],wr[10001],s1,ans; bool instack[10001]; line a[50001]; void tarjan(int x) {dfn[x]=low[x]=++stn;instack[x]=true;Stack.push(x);//入栈int y;for (int q=ls[x];q;q=a[q].next)//枚举连接到{y=a[q].t;if (!dfn[y])//如果没用计算{tarjan(y);//计算low[x]=min(low[x],low[y]);//更新low值}else if (instack[y] && low[x]>dfn[y])low[x]=dfn[y];}if (dfn[x]==low[x]){ltn++;while (Stack.size()>0){y=Stack.top();Stack.pop();ltm[ltn]++;lt[y]=ltn;if (y==x) break;}//归入同一个强连通分量} } int main() {scanf("%d%d",&n,&m);for (int i=1;i<=m;i++){scanf("%d%d",&a[i].h,&a[i].t);a[i].next=ls[a[i].h];ls[a[i].h]=i;}for (int i=1;i<=n;i++)if (dfn[i]==0) tarjan(i);//跑一遍for (int i=1;i<=m;i++)if (lt[a[i].t]!=lt[a[i].h]){wr[lt[a[i].h]]++;}//计算每个强连通的出度for (int i=1;i<=ltn;i++)if (!wr[i]){ans=i;s1++;//计算出度为0的数量}if (s1==1) printf("%d",ltm[ans]);else printf("0"); }

总结

以上是生活随笔为你收集整理的POJ2186-Popular Cows(流行的奶牛)【tarjan,强连通分量,图论】的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。