• luogu1726 上白泽慧音


    题目大意

      求一个有向图含节点数最多且结点编号从小到大排列字典序最小的强连通分量。

    注意事项

      HDU1269那道题题面、数据太弱,在这道题上把我害惨了。。。

    1. Dfs点u时,如果与u相连的一个点v有DfsN,v必须在栈内我们才能更新u的Low值。
    2. 我们要枚举每个点作为Dfs的起始点,不能只枚举一个。
    3. Dfs之前不必要把所有结点的标记清空,因为打过标记的点不会与后来Dfs到的点形成强连通分量,而且会导致重复计算。
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <stack>
    using namespace std;
    
    const int MAX_NODE = 5010, INF = 0x3f3f3f3f;
    
    struct Node
    {
    	vector<Node*> Next;
    	int DfsN, Low;
    	bool InStack;
    }_nodes[MAX_NODE];
    int TotNode, TotEdge;
    int AnsConIds[MAX_NODE], TempConIds[MAX_NODE];//Con::Connect
    int AnsConCnt, TempConCnt;
    int CurDfsN;
    stack<Node*> St;
    
    void AddEdge(int u, int v, int k)
    {
    	_nodes[u].Next.push_back(_nodes + v);
    	if (k == 2)
    		_nodes[v].Next.push_back(_nodes + u);
    }
    
    bool CmpArg(int *a, int *b, int n)
    {
    	for (int i = 1; i <= n; i++)
    		if (a[i] != b[i])
    			return a[i] < b[i];
    	return false;
    }
    
    void UpdateAns()
    {
    	if (TempConCnt >= AnsConCnt)
    	{
    		sort(TempConIds + 1, TempConIds + TempConCnt + 1);
    		if (TempConCnt > AnsConCnt || CmpArg(TempConIds, AnsConIds, AnsConCnt))
    		{
    			memcpy(AnsConIds, TempConIds, sizeof(TempConIds));
    			AnsConCnt = TempConCnt;
    		}
    	}
    }
    
    void PopStack(Node *cur)
    {
    	TempConCnt = 0;
    	Node *temp;
    	do {
    		temp = St.top();
    		temp->InStack = false;
    		TempConIds[++TempConCnt] = temp - _nodes;
    		St.pop();
    	} while (temp != cur);
    	UpdateAns();
    }
    
    void Dfs(Node *cur)
    {
    	cur->DfsN = ++CurDfsN;
    	cur->Low = cur->DfsN;
    	St.push(cur);
    	cur->InStack = true;
    	int nextCnt = cur->Next.size();
    	for (int i = 0; i < nextCnt; 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);
    }
    
    int main()
    {
    	scanf("%d%d", &TotNode, &TotEdge);
    	for (int i = 1; i <= TotEdge; i++)
    	{
    		int u, v, k;
    		scanf("%d%d%d", &u, &v, &k);
    		AddEdge(u, v, k);
    	}
    	CurDfsN = 0;
    	for (int i = 1; i <= TotNode; i++)
    	{
    		if (!_nodes[i].DfsN)
    		{
    			_printf("from %d:
    ", i);
    			while (St.size())
    				St.pop();
    			CurDfsN = 0;
    			Dfs(_nodes + i);
    		}
    	}
    	printf("%d
    ", AnsConCnt);
    	sort(AnsConIds + 1, AnsConIds + AnsConCnt + 1);
    	for (int i = 1; i <= AnsConCnt; i++)
    		printf("%d ", AnsConIds[i]);
    	printf("
    ");
    	return 0;
    }
    

      

  • 相关阅读:
    故乡
    webService和Restful
    java多线程(六)线程控制类
    java内存模型
    java多线程(五)线程通讯
    java多线程(四)死锁
    java多线程(三)线程的安全问题
    java多线程(二)线程的生命周期
    java多线程(一)创建线程的四种方式
    Spring Cloud(一)简单的微服务集成Eureka
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9384881.html
Copyright © 2020-2023  润新知