题目链接:
题目大意:
每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。
思路:
进行缩点,之后变成DAG图,记录出度为0的点,如果只有一个说明有解,否则答案为0。
统计那个出度为0的强连通分量内的点的数目即可。
1 #include2 #define IOS ios::sync_with_stdio(false);//不可再使用scanf printf 3 #define Max(a, b) ((a) > (b) ? (a) : (b))//禁用于函数,会超时 4 #define Min(a, b) ((a) < (b) ? (a) : (b)) 5 #define Mem(a) memset(a, 0, sizeof(a)) 6 #define Dis(x, y, x1, y1) ((x - x1) * (x - x1) + (y - y1) * (y - y1)) 7 #define MID(l, r) ((l) + ((r) - (l)) / 2) 8 #define lson ((o)<<1) 9 #define rson ((o)<<1|1)10 #pragma comment(linker, "/STACK:102400000,102400000")//栈外挂11 using namespace std;12 inline int read()13 {14 int x=0,f=1;char ch=getchar();15 while (ch<'0'||ch>'9'){ if (ch=='-') f=-1;ch=getchar();}16 while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}17 return x*f;18 }19 20 typedef long long ll;21 const int maxn = 10000 + 10;22 const int mod = 100003;//const引用更快,宏定义也更快23 const int INF = 1e9;24 vector G[maxn];25 int pre[maxn], lowlink[maxn], sccno[maxn], dfs_clock, scc_cnt;26 stack S;27 void dfs(int u)28 {29 pre[u] = lowlink[u] = ++dfs_clock;30 S.push(u);31 for(int i = 0; i < G[u].size(); i++)32 {33 int v = G[u][i];34 if(!pre[v])35 {36 dfs(v);37 lowlink[u] = Min(lowlink[u], lowlink[v]);38 }39 else if(!sccno[v])40 {41 lowlink[u] = Min(lowlink[u], pre[v]);42 }43 }44 if(lowlink[u] == pre[u])45 {46 scc_cnt++;47 for(;;)48 {49 int x = S.top();50 S.pop();51 sccno[x] = scc_cnt;52 if(x == u)break;53 }54 }55 }56 void find_scc(int n)57 {58 dfs_clock = scc_cnt = 0;59 Mem(sccno);60 Mem(pre);61 for(int i = 0; i < n; i++)if(!pre[i])dfs(i);62 }63 int chu[maxn];64 int main()65 {66 int n, m, u, v;67 scanf("%d%d", &n, &m);68 while(m--)69 {70 scanf("%d%d", &u, &v);71 u--, v--;72 G[u].push_back(v);73 }74 find_scc(n);75 for(int u = 0; u < n; u++)76 {77 for(int i = 0; i < G[u].size(); i++)78 {79 int v = G[u][i];80 if(sccno[u] != sccno[v])81 {82 chu[sccno[u]]++;83 }84 }85 }86 int tot = 0, t;87 for(int i = 1; i <= scc_cnt; i++)88 if(chu[i] == 0)tot++, t = i;89 int ans = 0;90 if(tot == 1)91 {92 for(int i = 0; i < n; i++)93 {94 if(sccno[i] == t)ans++;95 }96 }97 printf("%d\n", ans);98 return 0;99 }