Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 路径结束数最少的节点_C++_Algorithm_Graph_Depth First Search - Fatal编程技术网

C++ 路径结束数最少的节点

C++ 路径结束数最少的节点,c++,algorithm,graph,depth-first-search,C++,Algorithm,Graph,Depth First Search,算法课程有一个问题 你需要创建一个公司。公司有n名员工候选人 你应该选择尽可能多的员工。 然而,有几个限制。第一,政府的架构 公司必须严格分级:公司必须有一个 董事,董事有几个(可能是0个)直接下属, 他们每个人都有几个(可能是0个)直接下属,等等。 如果B是直接员工,则员工A称为员工B的老板 A或B的下属是A的直接下属,依此类推。 员工偶尔会玩一些1vs1游戏。如果员工A输给了 雇员B,A永远不能是B的老板。在这里及物性也成立。 如果A输给了B,B输给了C,A就永远不能成为C的老板,以此类推。

算法课程有一个问题

你需要创建一个公司。公司有n名员工候选人 你应该选择尽可能多的员工。 然而,有几个限制。第一,政府的架构 公司必须严格分级:公司必须有一个 董事,董事有几个(可能是0个)直接下属, 他们每个人都有几个(可能是0个)直接下属,等等。 如果B是直接员工,则员工A称为员工B的老板 A或B的下属是A的直接下属,依此类推。 员工偶尔会玩一些1vs1游戏。如果员工A输给了 雇员B,A永远不能是B的老板。在这里及物性也成立。 如果A输给了B,B输给了C,A就永远不能成为C的老板,以此类推。 作为输入,您将得到n、多个游戏以及每个游戏的结果 (谁输给了谁)。作为输出,您应该获得 公司

这是我得到的。 我们可以将博弈结果表示为有向图,其中节点表示员工。如果B输给A,则有一条边(A,B)。现在,如果对于每个节点,我们发现许多节点无法到达该节点,那么这些值的最大值就是问题的答案

我试图通过在每个节点上使用DFS来实现这一点,但这需要花费太长时间。因此,一定有一些解具有更好的渐近复杂性。你能给我一些想法吗?我附上我的密码

#include <algorithm>
#include <iostream>
#include <vector>
#include <stack>


class Graph {
    uint16_t number_of_vertices_;
    std::vector<std::vector<uint16_t>> adjacent_;
    void DFSUtil(uint16_t vertex);
public:
    std::vector<uint16_t> fooled_by_;

    explicit Graph(uint16_t number_of_vertices);

    void AddEdge(uint16_t first_vertex, uint16_t second_vertex) {
        adjacent_[first_vertex].push_back(second_vertex);
    }

    void FindTransitiveClosure();

    uint16_t FindMaxSizeOfCompany();
};


Graph::Graph(uint16_t number_of_vertices) {
    number_of_vertices_ = number_of_vertices;

    std::vector<std::vector<uint16_t>> adjacent(number_of_vertices);
    adjacent_ = adjacent;

    std::vector<uint16_t> fooled_by(number_of_vertices, number_of_vertices);
    fooled_by_ = fooled_by;
}


void Graph::DFSUtil(uint16_t vertex) {

    std::vector<bool> visited(number_of_vertices_, false);
    std::stack<uint16_t> stack;

    stack.push(vertex);
    visited[vertex] = true;

    uint16_t current_vertex;
    while (!stack.empty()) {
        current_vertex = stack.top();
        stack.pop();


        for (size_t i =0; i < adjacent_[current_vertex].size(); ++i) {
            if (!visited[adjacent_[current_vertex][i]]) {
                visited[adjacent_[current_vertex][i]] = true;
                --fooled_by_[adjacent_[current_vertex][i]];
                stack.push(adjacent_[current_vertex][i]);
            }
        }
    }
}


void Graph::FindTransitiveClosure() {
    for (uint16_t i = 0; i < number_of_vertices_; ++i) {
        DFSUtil(i);
    }
}


uint16_t Graph::FindMaxSizeOfCompany() {
    uint16_t max_sum = 0;

    for (uint16_t i = 0; i < number_of_vertices_; ++i) {
        if (max_sum < fooled_by_[i]) {
            max_sum = fooled_by_[i];
        }
    }

    return max_sum;
}


void ReadGraph(uint16_t number_of_edges, Graph &fool) {

    uint16_t first_vertex, second_vertex, won;
    for (uint16_t counter = 0; counter < number_of_edges; ++counter) {
        std::cin >> first_vertex >> second_vertex >> won;
        if (won == 1) {
            fool.AddEdge(first_vertex - 1, second_vertex - 1);
        }
        if (won == 2) {
            fool.AddEdge(second_vertex - 1, first_vertex - 1);
        }
    }
}


int main() {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);

    uint16_t number_of_vertices, number_of_edges;
    std::cin >> number_of_vertices >> number_of_edges;

    Graph fool(number_of_vertices);
    ReadGraph(number_of_edges, fool);

    fool.FindTransitiveClosure();

    std::cout << fool.FindMaxSizeOfCompany();

    return 0;
}

#包括
#包括
#包括
#包括
类图{
uint16 \u t \u顶点数\u;
std::向量邻接;
void DFSUtil(uint16_t顶点);
公众:
std::被u愚弄的向量u;
显式图(uint16个顶点的个数);
void AddEdge(uint16第一个顶点,uint16第二个顶点){
相邻的\u[第一个\u顶点]。向后推\u(第二个\u顶点);
}
void FindTransitiveClosure();
uint16_t FindMaxSizeOfCompany();
};
Graph::Graph(uint16个顶点的数量){
顶点数=顶点数;
std::向量相邻(顶点数);
相邻的=相邻的;
std::被愚弄的向量(顶点数,顶点数);
被愚弄了;
}
无效图::DFSUtil(uint16_t顶点){
std::访问的向量(顶点数,假);
std::堆栈;
堆栈推送(顶点);
访问[顶点]=真;
uint16当前顶点;
而(!stack.empty()){
当前_顶点=stack.top();
stack.pop();
对于(size_t i=0;i<相邻的_[当前顶点])。size();++i){
如果(!访问了[相邻的][当前的][i]]{
已访问[相邻的\[当前的\[顶点]]=true;
--被uu[相邻u[当前_顶点][i]愚弄u;
stack.push(相邻的_u[当前_顶点][i]);
}
}
}
}
void图::FindTransitiveClosure(){
对于(uint16_t i=0;i<顶点的数量u;++i){
行政长官(一);
}
}
uint16\u t图形::FindMaxSizeOfCompany(){
uint16最大和=0;
对于(uint16_t i=0;i<顶点的数量u;++i){
if(max_sum<被[i]愚弄了){
max_sum=被_[i]愚弄;
}
}
返回最大和;
}
void ReadGraph(uint16边数、图和傻瓜){
uint16第一个顶点、第二个顶点获胜;
对于(uint16_t计数器=0;计数器<边数;++计数器){
标准::cin>>第一个顶点>>第二个顶点>>获胜;
如果(韩元=1){
添加(第一个顶点-1,第二个顶点-1);
}
如果(韩元=2){
添加(第二个顶点-1,第一个顶点-1);
}
}
}
int main(){
std::ios_base::sync_with_stdio(false);
标准:cin.tie(无PTR);
uint16 \u t \u顶点数\u,边数\u;
std::cin>>顶点数>>边数;
图傻瓜(顶点数);
ReadGraph(边的数量,傻瓜);
fool.FindTransitiveClosure();

std::假设你已经得到了图的传递闭包,为什么解决方案不只是作为主管损失最少的人,而所有她没有失去的人都是她的下属呢?@PaulHankin我不确定我是否正确理解你的问题。如果是“失去”的话,你提出的确实是一个解决方案你的意思是直接的和间接的。你的解决方案的渐进复杂性是什么?哪怕输入数据花费的时间太长?你有给出正确结果的测试用例吗?@UlrichEckhardt我对每个节点进行DFS。如果我们假设节点数(n)大致等于边数,那么复杂性是O(n^2),O(n^3)如果图是稠密的。输入由50000个节点和50000条边限定。此解决方案通过了多次测试,但在随后的一次测试中超过了时间限制。我看不到此测试的输入,但我假设它有大n(当我计算传递闭包时,它超过了内存限制).假设你得到了图表的传递闭包,为什么解决方案不只是作为主管损失最少的人,而所有她没有失去的人都是她的下属呢?@PaulHankin我不确定我是否正确理解你的问题。如果是“失去”的话,你提出的确实是一个解决方案你的意思是直接的和间接的。你的解决方案的渐进复杂性是什么?哪怕输入数据花费的时间太长?你有给出正确结果的测试用例吗?@UlrichEckhardt我对每个节点进行DFS。如果我们假设节点数(n)大致等于边数,那么复杂性是O(n^2),O(n^3)如果图是稠密的。输入由50000个节点和50000条边限定。此解决方案通过了多次测试,但在后面的一次测试中超过了时间限制。我看不到此测试的输入,但我假设它有大n(当我计算传递闭包时,它超过了内存限制)。