• luogu2341 [HAOI2006]受欢迎的牛


    题目大意

      每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你算出有多少头奶牛可以当明星。

    思路

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #include <cassert>
    using namespace std;
    
    const int MAX_NODE = 10010;
    
    struct Block
    {
    	int Size;
    	bool NotLeaf;
    }_blocks[MAX_NODE];
    int _blockCnt;
    
    struct Node
    {
    	int Low, DfsN;
    	bool InStack;
    	vector<Node*> Next;
    	Block* BlockIn;
    }_nodes[MAX_NODE];
    int _vCount, DfsCnt;
    stack<Node*> St;
    
    
    void PopStack(Node *cur)
    {
    	Block *curBlock = _blocks + ++_blockCnt;
    	Node *temp;
    	do {
    		temp = St.top();
    		temp->InStack = false;
    		St.pop();
    		temp->BlockIn = curBlock;
    		curBlock->Size++;
    	} while (temp != cur);
    }
    
    void Dfs(Node *cur)
    {
    	cur->Low = cur->DfsN = ++DfsCnt;
    	cur->InStack = true;
    	St.push(cur);
    	for (unsigned int i = 0; i < cur->Next.size(); i++)
    	{
    		if (!cur->Next[i]->DfsN)
    		{
    			Dfs(cur->Next[i]);
    			cur->Low = min(cur->Low, cur->Next[i]->Low);
    		}
    		else if (cur->Next[i]->InStack)
    			cur->Low = min(cur->Low, cur->Next[i]->DfsN);
    	}
    	if (cur->Low == cur->DfsN)
    		PopStack(cur);
    }
    
    void Tarjan()
    {
    	for (int i = 1; i <= _vCount; i++)
    	{
    		if (!_nodes[i].DfsN)
    			Dfs(_nodes + i);
    		assert(St.size() == 0);
    	}
    }
    
    int GetLeafCnt()
    {
    	int leafCnt = 0;
    	for (int i = 1; i <= _vCount; i++)
    		for (unsigned int j = 0; j < _nodes[i].Next.size(); j++)
    			if (_nodes[i].BlockIn != _nodes[i].Next[j]->BlockIn)
    				_nodes[i].BlockIn->NotLeaf = true;
    	for (int i = 1; i <= _blockCnt; i++)
    		leafCnt += !_blocks[i].NotLeaf;
    	return leafCnt;
    }
    
    int GetAns()
    {
    	for (int i = 1; i <= _blockCnt; i++)
    		if (!_blocks[i].NotLeaf)
    			return _blocks[i].Size;
    	return -1;
    }
    
    int main()
    {
    	int totEdge;
    	scanf("%d%d", &_vCount, &totEdge);
    	for (int i = 1; i <= totEdge; i++)
    	{
    		int u, v;
    		scanf("%d%d", &u, &v);
    		_nodes[u].Next.push_back(_nodes + v);
    	}
    	Tarjan();
    	int leafCnt = GetLeafCnt();
    	if (leafCnt > 1)
    		printf("0
    ");
    	else
    		printf("%d
    ", GetAns());
    	return 0;
    }
    

      

  • 相关阅读:
    基于K-means聚类算法的图像分割 和 基于机器学习的图像二元分类
    .off文件三维数据读取并显示
    滑动窗口&Region Proposal&Selective Search&KMeans&二元分类(空间分割)
    ENVI+IDL遥感图像处理
    OpenCV与图像分割 边界检测
    SublimeText3追踪函数工具CTags设置及使用
    岗位要求
    bash shell脚本如何获取脚本所在目录
    mongodb获取到的可能已经沦为肉鸡的云服务器地址
    wireshark查看包显示:Packet size limitedduring capture
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9391840.html
Copyright © 2020-2023  润新知