C++ 图可排序性C++;

C++ 图可排序性C++;,c++,graph,theory,C++,Graph,Theory,所以我有一个家庭作业问题: 设G是n顶点上的有向图 1->2 2->3 3->1 Is not Sortable. 1->2 2->3 3->4 4->2 Is Sortable. 如果顶点可以从1到n进行清晰编号(没有两个顶点的编号相同),则调用Gsortable,以便每个具有传入边的顶点至少有一个编号较低的前置顶点。例如,让 num(v)< /代码>被分配给顶点 v,并考虑一个顶点 x>代码>来自三个其他顶点的输入边 r>代码>, y>代码>

所以我有一个家庭作业问题:

G
n
顶点上的有向图

1->2
2->3
3->1

Is not Sortable.

1->2
2->3
3->4
4->2

Is Sortable.
如果顶点可以从
1
n
进行清晰编号(没有两个顶点的编号相同),则调用
G
sortable,以便每个具有传入边的顶点至少有一个编号较低的前置顶点。例如,让<代码> num(v)< /代码>被分配给顶点<代码> v<代码>,并考虑一个顶点<代码> x>代码>来自三个其他顶点的输入边<代码> r>代码>,<代码> y>代码>和<代码> z < /代码>。然后
NUM(x)
必须大于
NUM(r)
NUM(y)
NUM(z)
中的至少一个

此外,算法必须是线性的<代码>O(| V |+| E |)


遍历图很容易,但我不知道如何检查顶点的父对象,以查看父对象的any的数量是否低于子对象的数量

我应该如何保存我所在顶点的父顶点的引用


以下邻接列表是输入文件(仅对实际测试用例的8k顶点进行采样)


这个问题可以在C++中完成,我选择C++来使用STL。< /P> 我使用邻接列表存储图形,输入文件是边列表。

这样可以吗

  • 创建一个邻接矩阵。如果
    指向
    ,则放入
    1
    在那里
  • 向下扫描每个
    col
    到第一个
    1
    。如果
    col
    >s; 返回s; } 使用graph=std::vector; 图形读取(标准::istream&is){ 图G; 向量边; 地图标签; int max=-1; //假设输入是一个边定义列表,每行一个。每行是: //“label->label”,其中空格是可选的,“->”是一个文本,并且 //“标签”不包含“->”或空白。 //如果我们可以假设合理的int标签,这可以大大简化。 std::字符串l; while(std::getline(is,l)){ //解析标签。 const auto n=l.find(“->”); 常数自动lhs=微调(l.substr(0,n)); 常数自动rhs=微调(l.substr(n+2)); //将标签转换为整数。 自动i=标签。查找(lhs); 如果(i==labels.end()){labels[lhs]=++max;} 自动j=标签。查找(rhs); 如果(j==labels.end()){labels[rhs]=++max;} //记住边缘。 推回({labels[lhs],labels[rhs]}); } //调整邻接矩阵的大小。 G.调整大小(最大值+1); 对于(auto&v:G){v.resize(max+1);} //标记边缘。 对于(const auto&e:edges){G[e.first][e.second]=1;} 返回G; } 布尔可移植(常数图和G){ 常数int s=G.size(); 用于(整数列=0;列 GCC 4.7.3:g++-Wall-Wextra-std=c++0x sortable-graph.cpp

    #include <iostream>
    #include <map>
    #include <sstream>
    #include <string>
    #include <vector>
    
    std::string trim(const std::string& str) {
      std::string s;
      std::stringstream ss(str);
      ss >> s;
      return s;
    }
    
    using graph = std::vector<std::vector<int>>;
    
    graph read(std::istream& is) {
      graph G;
      std::vector<std::pair<int, int>> edges;
      std::map<std::string, int> labels;
      int max = -1;
    
      // Assume input is a list of edge definitions, one per line. Each line is:
      // "label -> label" where white space is optional, "->" is a literal, and
      // "label" does not contain "->" or white space.
    
      // This can be vastly simplified if we can assume sensible int labels.
    
      std::string l;
      while (std::getline(is, l)) {
        // Parse the labels.
        const auto n = l.find("->");
        const auto lhs = trim(l.substr(0, n));
        const auto rhs = trim(l.substr(n + 2));
    
        // Convert the labels to ints.
        auto i = labels.find(lhs);
        if (i == labels.end()) { labels[lhs] = ++max; }
        auto j = labels.find(rhs);
        if (j == labels.end()) { labels[rhs] = ++max; }
    
        // Remember the edge.
        edges.push_back({labels[lhs], labels[rhs]});
      }
    
      // Resize the adjacency matrix.
      G.resize(max+1);
      for (auto& v : G) { v.resize(max+1); }
    
      // Mark the  edges.
      for (const auto& e : edges) { G[e.first][e.second] = 1; }
    
      return G;
    }
    
    bool isSortable(const graph& G) {
      const int s = G.size();
      for (int col = 0; col < s; ++col) {
        for (int row = 0; row < s; ++row) {
          if (G[row][col] == 1) {
            if (col <= row) { return false; }
            break;
          }
        }
      }
      return true;
    }
    
    void print(std::ostream& os, const graph& G) {
      const int s = G.size();
      for (int row = 0; row < s; ++row) {
        for (int col = 0; col < s; ++col) {
          os << G[row][col] << " ";
        }
        os << "\n";
      }
    }
    
    int main() {
      const auto G = read(std::cin);
      print(std::cout, G);
      const auto b = isSortable(G);
    
      std::cout << (b ? "Is Sortable.\n" : "Is not Sortable.\n");
    }
    
    #include <iostream>
    #include <map>
    #include <sstream>
    #include <string>
    #include <vector>
    
    std::string trim(const std::string& str) {
      std::string s;
      std::stringstream ss(str);
      ss >> s;
      return s;
    }
    
    using edges = std::vector<std::pair<int, int>>;
    
    void read(std::istream& is, edges& E, int& max) {
      std::map<std::string, int> labels;
      max = -1;
    
      // Assume input is a list of edge definitions, one per line. Each line is:
      // "label -> label" where white space is optional, "->" is a literal, and
      // "label" does not contain "->" or white space.
    
      // This can be vastly simplified if we can assume sensible int labels.
    
      std::string l;
      while (std::getline(is, l)) {
        // Parse the labels.
        const auto n = l.find("->");
        const auto lhs = trim(l.substr(0, n));
        const auto rhs = trim(l.substr(n + 2));
    
        // Convert the labels to ints.
        auto i = labels.find(lhs);
        if (i == labels.end()) { labels[lhs] = ++max; }
        auto j = labels.find(rhs);
        if (j == labels.end()) { labels[rhs] = ++max; }
    
        // Remember the edge.
        E.push_back({labels[lhs], labels[rhs]});
      }
    }
    
    bool isSortable(const edges& E, int max) {
      std::vector<int> num(max+1, max+1);
      for (const auto& e : E) {
        num[e.second] = std::min(e.first, num[e.second]);
      }
    
      for (int i = 0; i < num.size(); ++i) {
        if (num[i] != max + 1 && i <= num[i]) { return false; }
      }
    
      return true;
    }
    
    int main() {
      edges E;
      int max;
      read(std::cin, E, max);
      const auto b = isSortable(E, max);
    
      std::cout << (b ? "Is Sortable.\n" : "Is not Sortable.\n");
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    标准::字符串修剪(常量标准::字符串和字符串){
    std::字符串s;
    std::stringstream ss(str);
    ss>>s;
    返回s;
    }
    使用edges=std::vector;
    无效读取(标准::istream&is、edges&E、int&max){
    地图标签;
    max=-1;
    //假设输入是一个边定义列表,每行一个。每行是:
    //“label->label”,其中空格是可选的,“->”是一个文本,并且
    //“标签”不包含“->”或空白。
    //如果我们可以假设合理的int标签,这可以大大简化。
    std::字符串l;
    while(std::getline(is,l)){
    //解析标签。
    const auto n=l.find(“->”);
    常数自动lhs=微调(l.substr(0,n));
    常数自动rhs=微调(l.substr(n+2));
    //将标签转换为整数。
    自动i=标签。查找(lhs);
    如果(i==labels.end()){labels[lhs]=++max;}
    自动j=标签。查找(rhs);
    如果(j==labels.end()){labels[rhs]=++max;}
    //记住边缘。
    E.向后推({标签[lhs],标签[rhs]});
    }
    }
    布尔可移植(常数边和E,整数最大值){
    std::向量数(max+1,max+1);
    用于(常数自动和e:e){
    num[e.second]=std::min(e.first,num[e.second]);
    }
    对于(int i=0;i如果(num[i]!=max+1&&我会努力突出你遇到的具体问题。显然,我们不会为你做家庭作业,但我们很乐意帮助你清除具体的绊脚石。@Veedrac谢谢你,我的帖子现在看起来好多了,我主要是在回顾我正在使用的顶点的父母时遇到问题(不确定有什么更好的方法来说明这个问题)。你不是说你选择了C++作为STL?@ MARCELCOANTOS,这确实是我的意思,已经做了修正。我已经考虑过(并且开始尝试)使用一个修改的DFS来完成任务,但是它让我质疑如何确定一个父母是否有一个较低的NUMLUP;
    
    #include <iostream>
    #include <map>
    #include <sstream>
    #include <string>
    #include <vector>
    
    std::string trim(const std::string& str) {
      std::string s;
      std::stringstream ss(str);
      ss >> s;
      return s;
    }
    
    using edges = std::vector<std::pair<int, int>>;
    
    void read(std::istream& is, edges& E, int& max) {
      std::map<std::string, int> labels;
      max = -1;
    
      // Assume input is a list of edge definitions, one per line. Each line is:
      // "label -> label" where white space is optional, "->" is a literal, and
      // "label" does not contain "->" or white space.
    
      // This can be vastly simplified if we can assume sensible int labels.
    
      std::string l;
      while (std::getline(is, l)) {
        // Parse the labels.
        const auto n = l.find("->");
        const auto lhs = trim(l.substr(0, n));
        const auto rhs = trim(l.substr(n + 2));
    
        // Convert the labels to ints.
        auto i = labels.find(lhs);
        if (i == labels.end()) { labels[lhs] = ++max; }
        auto j = labels.find(rhs);
        if (j == labels.end()) { labels[rhs] = ++max; }
    
        // Remember the edge.
        E.push_back({labels[lhs], labels[rhs]});
      }
    }
    
    bool isSortable(const edges& E, int max) {
      std::vector<int> num(max+1, max+1);
      for (const auto& e : E) {
        num[e.second] = std::min(e.first, num[e.second]);
      }
    
      for (int i = 0; i < num.size(); ++i) {
        if (num[i] != max + 1 && i <= num[i]) { return false; }
      }
    
      return true;
    }
    
    int main() {
      edges E;
      int max;
      read(std::cin, E, max);
      const auto b = isSortable(E, max);
    
      std::cout << (b ? "Is Sortable.\n" : "Is not Sortable.\n");
    }