zoukankan      html  css  js  c++  java
  • UVa 872

    本题要求输出所有拓扑排序的序列。

    还好本题的数据量不是非常大。限制在26个大写英文字母,故此能够使用递归法输出。

    这个递归输出所有解在Leetcode非常多这种题目的,不小心的话,还是非常难调试的。

    整体考了递归和拓扑排序,还有推断能否够拓扑排序-就是是否图有环。

    考了三大知识点。难度还是有的。由于数据量不大,故此推断环能够使用一般递归方法。递归仅仅须要注意细节就好了。


    #include <stdio.h>
    #include <vector>
    #include <string.h>
    using namespace std;
    const int ALPHA = 26;
    bool gra[ALPHA][ALPHA];
    int id = 0, len = 0;
    const int MAX_B = 512;
    char buf[MAX_B];
    
    char getFromBuf()
    {
    	if (id >= len)
    	{
    		len = fread(buf, 1, MAX_B, stdin);
    		id = 0;
    	}
    	return buf[id++];
    }
    
    struct Subset
    {
    	int p, r;
    };
    
    Subset subs[ALPHA];
    
    int findParent(int u)
    {
    	if (u != subs[u].p) subs[u].p = findParent(subs[u].p);
    	return subs[u].p;
    }
    
    void unionTwo(int x, int y)
    {
    	int xroot = findParent(x);
    	int yroot = findParent(y);
    	if (subs[xroot].r < subs[yroot].r) subs[xroot].p = yroot;
    	else
    	{
    		subs[yroot].p = xroot;
    		if (subs[yroot].r == subs[xroot].r) subs[xroot].r++;
    	}
    }
    
    void initSubs()
    {
    	for (int i = 0; i < ALPHA; i++)
    	{
    		subs[i].p = i;
    		subs[i].r = 0;
    	}
    }
    
    bool isCycle()
    {
    	initSubs();
    	for (int i = 0; i < ALPHA; i++)
    	{
    		for (int j = 0; j < ALPHA; j++)
    		{
    			if (i == j || !gra[i][j]) continue;
    			int ip = findParent(i);
    			int jp = findParent(j);
    			if (ip == jp) return true;
    			unionTwo(i, j);
    		}
    	}
    	return false;
    }
    
    int rs[ALPHA];
    bool vis[ALPHA];
    void printAllTopologicalOrders(int N, int rsid = 0)
    {
    	if (rsid == N)	//递归究竟了,打印结果
    	{
    		if (rsid > 0) putchar(rs[0]+'A');
    		for (int i = 1; i < rsid; i++)
    		{
    			putchar(' ');
    			putchar(rs[i]+'A');
    		}
    		putchar('
    ');
    		return ;
    	}
    	for (int i = 0; i < ALPHA; i++)
    	{
    		if (vis[i]) continue;//这里要推断,漏了这句。好难dubg啊。

    要细致用脑去模拟过程才干发现!!

    if (!gra[i][i]) continue; //没有这个点,跳过 int j = 0; for ( ; j < ALPHA; j++)//检查i是否有入度 { if (i != j && !vis[j] && gra[j][i]) break; } if (j == ALPHA) //找到入度为零的点i了 { vis[i] = true; rs[rsid] = i; printAllTopologicalOrders(N, rsid+1); vis[i] = false; } } } int main() { int T; scanf("%d", &T); while (T--) { int N = 0; memset(gra, 0, sizeof(gra)); char a = getFromBuf(); while ((a == ' ' || a == ' ') && len) a = getFromBuf(); while (a != ' ' && len) { if ('A' <= a && a <= 'Z') { gra[a-'A'][a-'A'] = 1;//代表有点 N++; } a = getFromBuf(); } while ((a == ' ' || a == ' ') && len) a = getFromBuf(); while (a != ' ' && len) { int u = a - 'A'; a = getFromBuf(); a = getFromBuf(); int v = a - 'A'; gra[u][v] = 1; a = getFromBuf(); if (a == ' ') break; a = getFromBuf(); } fill(vis, vis+ALPHA, false); if (isCycle()) puts("NO"); else { printAllTopologicalOrders(N); } if (T) putchar(' '); } return 0; }



  • 相关阅读:
    提前期分类
    物料属性,MRP/MPS属性
    ASP.NET刷新页面的一些方法
    Nothing 和 Is
    三层架构与MVC
    ADO.NET
    软件工程之数据流程图(DFD Data Flow Diagram)
    VB.NET小结
    推荐开发人员看的具有影响力的书籍
    C++考试
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5349685.html
Copyright © 2011-2022 走看看