Descriptionios
Inputweb
Output算法
Sample Inputide
3 3 1 2 2 1 2 3
Sample Outputthis
1題意:n頭牛,每頭牛的心目中都有本身最歡迎的牛,歡迎可傳遞,若是a認爲b最受歡迎,b認爲c最受歡迎,那麼a認爲c也受歡迎。統計能出本身外能讓其它全部的牛認爲受歡迎的牛的數量題解:統計全部點到一個點均可達的數量。有向無環圖中全部的點至某個點可達,那麼這個點的出度必爲0也是惟一的出度爲0的點.用tarjan算法縮點,統計縮點後的圖中出度爲0的數量,若是數量>1,那麼不存在不然輸出該點的強連通份量點的個數。#include<stdio.h>#include<iostream>#include<stack>#include<vector>#include<string.h>using namespace std;int visit[10001];int dfn[10001],low[10001],head[10001],n,m,ret,ans,ti;int flag[10001];stack<int> st;vector<int> v[10001];int du[10001][2];struct lmx{ int u; int v; int next;};lmx a[50001];void add(int u,int v){ a[ret].u=u; a[ret].v=v; a[ret].next=head[u]; head[u]=ret++;}void tarjan(int s){ dfn[s]=low[s]=++ti; st.push(s); visit[s]=1; int k; for(int i=head[s];i!=-1;i=a[i].next) { int k=a[i].v; if(!dfn[k]) { tarjan(k); if(low[s]>low[k]) low[s]=low[k]; } else if(visit[k]&&low[s]>dfn[k]) low[s]=dfn[k]; } if(dfn[s]==low[s]) { ans++; do{ k=st.top(); st.pop(); visit[k]=0; flag[k]=ans; v[ans].push_back(k); }while(s!=k); }}int cnt(){ int i,cnt=0,pos; if(ans==1) return n; memset(du,0,sizeof(du)); for(i=0;i<m;i++) { int u=flag[a[i].u],v=flag[a[i].v]; if(u==v) continue; du[u][0]++; du[v][1]++; } for(i=1;i<=ans;i++) { if(du[i][0]==0) {cnt++;pos=i;} } if(cnt>1) return 0; return v[pos].size();}int main(){ int i; while(scanf("%d %d",&n,&m)!=EOF) { memset(visit,0,sizeof(visit)); memset(dfn,0,sizeof(dfn)); memset(head,-1,sizeof(head)); ans=ti=ret=0; for(i=0;i<m;i++) { int a,b; scanf("%d %d",&a,&b); add(a,b); } for(i=1;i<=n;i++) v[i].clear(); for(i=1;i<=n;i++) { if(!dfn[i]) tarjan(i); } printf("%d\n",cnt()); } return 0;}