poj 1094 Sorting It All Out 解题报告

题目链接:http://poj.org/problem?id=1094

题目意思:给出 n 个待排序的字母 和 m 种关系,问需要读到第 几 行可以确定这些字母的排列顺序或者有矛盾的地方,又或者虽然具体的字母顺序不能确定但至少不矛盾。这些关系均是这样的一种形式: 字母1 < 字母2

  这道题目属于图论上的拓扑排序,由于要知道读入第几行可以确定具体的顺序,所以每次读入都需要进行拓扑排序来检验,这时每个点的入度就需要存储起来,所以就有了代码中memcpy 的使用了。

拓扑排序的思路很容易理解,但写起来还是需要注意很多细节。参考了别人的代码,第一次写,受益匪浅啊。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <vector>
  5 #include <queue>
  6
  7 using namespace std;
  8
  9 const int maxn = 26 + 5;
 10 vector<int> vi[maxn];
 11 queue<int> q;
 12 int in[maxn], temp[maxn];
 13 int n, m, cnt;
 14 char ans[maxn], input[5];
 15
 16 bool check(int x, int y)     // 检查之前是否插入过该边
 17 {
 18     for (int i = 0; i < vi[x].size(); i++)
 19     {
 20         if (vi[x][i] == y)
 21             return true;
 22     }
 23     return false;
 24 }
 25
 26 int Toposort()
 27 {
 28     while (!q.empty())
 29         q.pop();
 30     for (int i = 0; i < n; i++) // 将入度为0的点入队
 31     {
 32         if (!in[i])
 33             q.push(i);
 34     }
 35     bool unsure = false;
 36     cnt = 0;
 37     while (!q.empty())    // 取出第一个入度为0的点
 38     {
 39         if (q.size() > 1) // 假如有n个点的DAG入度为0的点只有一个,那么就可以确定已排好序
 40             unsure = true;
 41         int tmp = q.front();
 42
 43         ans[cnt++] = tmp + ‘A‘;
 44         q.pop();
 45         for (int i = 0; i < vi[tmp].size(); i++) // 该点引出的边删除
 46         {
 47             in[vi[tmp][i]]--;      // 即入度减1
 48             if (!in[vi[tmp][i]])  // 恰好入度减1后,该点入度变为0
 49                 q.push(vi[tmp][i]);
 50         }
 51     }
 52     if (cnt < n)   // 有环
 53         return 2;
 54     if (unsure)    // 有待进一步斟酌
 55         return 3;
 56     return 1;      // 已经排好序
 57 }
 58
 59 int main()
 60 {
 61     int step, flag;
 62     while (scanf("%d%d", &n, &m) != EOF && (m || n))
 63     {
 64         for (int i = 0; i < maxn; i++)
 65             vi[i].clear();
 66         bool ok = false;
 67         memset(in, 0, sizeof(in));
 68         for (int i = 1; i <= m; i++)
 69         {
 70             scanf("%s", input);
 71             if (ok)
 72                 continue;
 73             int l = input[0] - ‘A‘;
 74             int r = input[2] - ‘A‘;
 75             if (!check(l, r))
 76             {
 77                 vi[l].push_back(r);
 78                 in[r]++;
 79             }
 80             memcpy(temp, in, sizeof(in));   // 每个点的入度数处理前先拷贝一份以待下一次输入再用
 81             flag = Toposort();
 82             memcpy(in, temp, sizeof(temp));
 83             if (flag != 3)   // 暂时不能判断属于哪种情况,先保存step数
 84             {
 85                 step = i;
 86                 ok = true;
 87             }
 88         }
 89         if (flag == 1)
 90         {
 91             ans[cnt] = ‘\0‘;
 92             printf("Sorted sequence determined after %d relations: %s.\n", step, ans);
 93         }
 94         else if (flag == 2)
 95             printf("Inconsistency found after %d relations.\n", step);
 96         else
 97             printf("Sorted sequence cannot be determined.\n");
 98     }
 99     return 0;
100 }

poj 1094 Sorting It All Out 解题报告

时间: 2024-10-12 22:36:23

poj 1094 Sorting It All Out 解题报告的相关文章

拓扑序列变形 之 poj 1094 Sorting It All Out

/* 拓扑序列变形 之 poj 1094 Sorting It All Out 变形: 在每消去唯一一个入度为0的点后,只剩下唯一一个入度为0的点. 这样获得的n个点才是排序好的. */ 1 #include <iostream> 2 #include <cstdlib> 3 #include <cstdio> 4 #include <cstddef> 5 #include <iterator> 6 #include <algorithm&

最小生成树,POJ和HDU几道题目的解题报告(基于自己写的模板)

首先POJ题目: 链接:1251 Jungle Roads 题目大意:纯求最小生成树,结果为最小权值边的和.采用邻接表 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <vector> 4 #include <queue> 5 using namespace std; 6 7 #define maxn 30 //最大顶点个数 8 int n; //顶点数,边数 9 10 struct arcn

poj 1094 Sorting It All Out[ topo]

传送门:http://poj.org/problem?id=1094 Sorting It All Out Description An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequen

USACO Section2.1 Sorting a Three-Valued Sequence 解题报告

sort3解题报告 —— icedream61 博客园(转载请注明出处)------------------------------------------------------------------------------------------------------------------------------------------------[题目] 给你N,而后给出N个数,每个数都是1~3中的一个.请问,要把这个数列升序排好,最少需要进行几次两两交换?[数据范围] 1<=N<

[ACM] POJ 1094 Sorting It All Out (拓扑排序)

Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26801   Accepted: 9248 Description An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from sm

nyoj 349&amp;Poj 1094 Sorting It All Out

Sorting It All Out 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B,

POJ 1094 Sorting It All Out(拓扑排序判环)

题目链接:http://poj.org/problem?id=1094 题目: Description An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to largest. For example, the sorted sequence A, B, C, D

POJ 1094 Sorting It All Out 拓扑排序

Sorting It All Out Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%lld & %llu Description An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from smallest to

POJ 1094 Sorting It All Out【floyd传递闭包+拓扑排序】

Sorting It All Out Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 31994 Accepted: 11117 Description An ascending sorted sequence of distinct values is one in which some form of a less-than operator is used to order the elements from small