1. 程式人生 > >[bzoj1051]Popular Cows

[bzoj1051]Popular Cows

hint amp break back pan ack tput sin 數據

剛剛被ysy在聯考裏虐了,差點爆tan(pi/4),只好來bzoj尋求安慰再被虐一次233

tarjan是什麽智障東西不想打我好弱啊,tarjan都不會打)

Description

  每一頭牛的願望就是變成一頭最受歡迎的牛。現在有N頭牛,給你M對整數(A,B),表示牛A認為牛B受歡迎。 這 種關系是具有傳遞性的,如果A認為B受歡迎,B認為C受歡迎,那麽牛A也認為牛C受歡迎。你的任務是求出有多少頭 牛被所有的牛認為是受歡迎的。

Input

  第一行兩個數N,M。 接下來M行,每行兩個數A,B,意思是A認為B是受歡迎的(給出的信息有可能重復,即有可 能出現多個A,B)

Output

  一個數,即有多少頭牛被所有的牛認為是受歡迎的。

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

HINT

100%的數據N<=10000,M<=50000 這道題很裸的SCC吧,鑒於網上tarjan的code太多了,我還是打一個醜醜的dfs湊個數吧(tarjan異端中的一股清流) 要註意圖不聯通的情況,這時候沒有牛受歡迎。 代碼: 技術分享
#include<vector>
#include<cstdio>
#include<cstring>
using std::vector;
const int MAX_V=10000;
int V,M;
vector<int
>G[MAX_V],rG[MAX_V]; vector<int>vs; bool used[MAX_V]; int cmp[MAX_V]; void add_edge(int s,int t){G[s].push_back(t); rG[t].push_back(s);} void dfs(int v){ used[v]=1; for(int i=0;i<G[v].size();i++)if(!used[G[v][i]])dfs(G[v][i]); vs.push_back(v); } void rdfs(int v,int k){ used[v]
=1; cmp[v]=k; for(int i=0;i<rG[v].size();i++)if(!used[rG[v][i]])rdfs(rG[v][i],k); } int scc(){ memset(used,0,sizeof(used)); for(int v=0;v<V;v++)if(!used[v])dfs(v); memset(used,0,sizeof(used)); int k=0; for(int i=vs.size()-1;i>=0;i--)if(!used[vs[i]])rdfs(vs[i],k++); return k; } int main(){ scanf("%d%d",&V,&M); for(int i=0;i<M;i++){ int a,b;scanf("%d%d",&a,&b);add_edge(a-1,b-1); } int n=scc(),u=0,num=0; for(int v=0;v<V;v++)if(cmp[v]==n-1)u=v,num++; memset(used,0,sizeof(used)); rdfs(u,0); for(int i=0;i<V;i++) if(!used[i]){ num=0; break; } printf("%d\n",num); return 0; }
View Code

[bzoj1051]Popular Cows