拿两个!这个是 O(|V|+|E|)。
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 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");
}