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;列#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");
}