1. 程式人生 > >Poj 2186 Popular Cows(Tarjan 強連通縮點)

Poj 2186 Popular Cows(Tarjan 強連通縮點)

min == cows 縮點 clas ons num 有一個 pro

傳送門:Poj 2186

題意:給你n頭牛,m種關系,A牛認為B牛是popular的,B牛認為C牛是popular的,則A也認為C是popular的,問最終有幾頭被所有牛認為是popular的牛

題解:強連通縮點基礎題(雖然我Tarjan和縮點都是對的,但是最終討論判斷的時候寫垮了(寫了3天。。。。還不是你懶!!!!過年劃水這麽多天縮點後找出度為零的點個數。然後討論是否有這樣子的點,如果沒有則全都是(整個都是強連通圖),如果只有一個,那麽那個強連通分量所含的牛的個數就是所求解,如果有多個那麽都是不是。

#include<iostream>
#include<cstdio>
using
namespace std; const int N =1e4+5; int head[N]; int nx[N*N]; int to[N*N]; int tot=1; int vis[N]; int comNum; int comMap[N]; int Stack[N]; int Stacksize; int n,m; int dfn[N],low[N]; int indegree[N],outdegree[N]; int Map[N]; void make_list(int u,int v){ to[tot]=v; nx[tot]=head[u]; head[u]
=tot++; } void dfs(int u,int step){ dfn[u]=low[u]=step; vis[u]=1; Stack[++Stacksize]=u; for(int i=head[u];i;i=nx[i]){ int v=to[i]; if(vis[v]==0)dfs(v,step+1); if(vis[v]==1)low[u]=min(low[u],low[v]); } if(dfn[u]==low[u]){ comNum++; int sum=0
; int k; do{ sum++; k=Stack[Stacksize--]; comMap[k]=comNum; vis[k]=2; }while(k!=u); Map[comNum]=sum; } } void tarjan(){ for(int i=1;i<=n;i++){ if(!vis[i])dfs(i,1); } } int main(){ while(~scanf("%d %d",&n,&m)){ memset(head,0,sizeof(head)); memset(indegree,0,sizeof(indegree)); memset(outdegree,0,sizeof(outdegree)); comNum=Stacksize=0; memset(Map,0,sizeof(Map)); memset(vis,0,sizeof(vis)); for(int i=0;i<m;i++){ int a,b; scanf("%d%d",&a,&b); make_list(a,b); } tarjan(); for(int u=1;u<=n;u++){ for(int i=head[u];i;i=nx[i]){ int v=to[i]; if(comMap[u]!=comMap[v]){ indegree[comMap[v]]++; outdegree[comMap[u]]++; } } } int ans=0; int po=0; for(int i=1;i<=comNum;i++){ if(outdegree[i]==0){ ans+=Map[i]; po++; } } if(po>1)ans=0; printf("%d\n",ans); } return 0; }

Poj 2186 Popular Cows(Tarjan 強連通縮點)