传送门:
题意:给你n头牛,m种关系,A牛认为B牛是popular的,B牛认为C牛是popular的,则A也认为C是popular的,问最终有几头被所有牛认为是popular的牛
题解:强连通缩点基础题(虽然我Tarjan和缩点都是对的,但是最终讨论判断的时候写垮了(写了3天。。。。还不是你懒!!!!过年划水这么多天缩点后找出度为零的点个数。然后讨论是否有这样子的点,如果没有则全都是(整个都是强连通图),如果只有一个,那么那个强连通分量所含的牛的个数就是所求解,如果有多个那么都是不是。
#include#include 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 1)ans=0; printf("%d\n",ans); } return 0;}