刚刚被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; }
时间: 2024-10-05 20:36:37