• 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;
    }
    

      

  • 相关阅读:
    改变form里面input,textarea.select等的默认样式
    serialize() 方法
    纯css实现互动清单
    less学习笔记
    竖直手风琴导航菜单栏
    植树节快到了-那就种棵决策树吧
    简单写个logictic回归
    爬取纽约时报特定关键词新闻并计数
    (数学建模)非线性规划
    (CV学习笔记)看图说话(Image Captioning)-2
  • 原文地址:https://www.cnblogs.com/headboy2002/p/9384881.html
Copyright © 2020-2023  润新知