DAG中最长的路径

时间:2016-11-15 08:30:35

标签: c++ algorithm debugging onlinejudge

我最近开始编程(使用C ++),我已经介绍了这个名为UVa OnlineJudge的网站。这是一个可以提交问题解决方案并让他们通过服务器进行测试的地方。我已经开始解决他们的一些问题了。但是今天,我遇到了一个我似乎无法找到的问题。

执行Longest Path in an Unweighted DAG,我设法在他们的调试模式下解决所有情况。对我而言,我的代码看起来非常好。可能有点太乱了,但这不应该有任何区别。不过,我收到错误答案"我提交代码后,在0.03秒的运行时间后反馈。

我认为这是内存/ IO问题,但我可能(非常)错了。任何帮助将不胜感激。

提前抱歉,只需在main()中写下所有内容:

//my plan is to use topsort
//locate the starting point in the topological map
//then use a simplified dijkstra algorithm to do the rest

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;

class Vertex
{
public:
    int name;
    vector<int> edge;  //outgoing edges
    int weight=0;
    int inc=0;  //number of incoming edges
};


int main()
{
    int n;
    int l=1;
    while(cin>>n&&n!=0)
    {
        //initializing
        vector<Vertex> cities;
        for(int i=0; i<n; i++)
        {
            Vertex c;
            c.name=i;
            cities.push_back(c);
        }

        //reading input
        int start;
        cin>>start;
        start-=1;
        int a, b;
        vector<int> useless;
        while(cin>>a>>b&&a!=0&&b!=0)
        {
            b-=1; //re-index from 0 instead of 1
            a-=1;
            cities[a].edge.push_back(b);  //enlists b as target vertex
            cities[b].inc++;   //adds 1 to b's number of incoming edges
        }


        //topsort
        vector<int> map; //indexes the cities in topological order, starting from 0
        vector<Vertex> S;
        for(auto it : cities) //finds all cities without roads TO them, and puts them in S
        {
            if(it.inc==0)
            {
                S.push_back(it);
            }
        }
        while(S.empty()==false)
        {
            for(auto it : S[0].edge)
            {
                cities[it].inc-=1;
                if(cities[it].inc==0)
                    S.push_back(cities[it]);
            }
            map.push_back(S[0].name);
            S.erase(S.begin());
        }

        /*for(auto it : map)
            cout<<it<<' ';
        cout<<'\n';  //outputs the topological map for checking*/

        int x=0,y; //x is the length of the longest path (yet), and y is the destination of that path. If multiple paths are equally max long, pick the one with smallest y
        int startp=0; //find position of start in the topological map
        for(auto it : map)
        {
            if (it==start)
                break;

            else startp++;
        }

        for(vector<int>::iterator it = map.begin()+startp; it<map.end(); it++)
        {
            //checks if it is record length
            if (cities[*it].weight>x)
            {
                x=cities[*it].weight;
                y=cities[*it].name;
            }
            else if(cities[*it].weight==x)
                if(cities[*it].name<y)
                    y=cities[*it].name;

            //handles its edges
            for(auto itt : cities[*it].edge)
            {
                if(cities[itt].weight<cities[*it].weight+1)
                    cities[itt].weight=cities[*it].weight+1;

            }
        }

        y+=1;
        start+=1;

        cout<<"Case "<<l<<": The longest path from "<<start<<" has length "<<x<<", finishing at "<<y<<'.'<<'\n'<<'\n';
        l++;
    }

    return 0;
}

1 个答案:

答案 0 :(得分:0)

我不知道为什么你的代码不起作用,但我认为你应该对你说明这个问题有一个更清洁的解决方案。简单的DP方法可以优雅地解决它。 E 是包含边信息的向量( E [i] 是包含与节点 i 相邻的节点列表的向量)。 R 是一个查找表,用于不反复从顶点 n 重新计算相同的最长路径。

std::pair<int,int> longest(vector<vector<int>>& E, vector<pair<int,int>>& R, int n) {
    if(E[n].size() == 0)
        return make_pair(0,n);

    if(R[n].first != -1)
        return R[n];

    for(auto& e : E[n]) {
        std::pair<int,int> p = longest(E,R,e);
        if(p.first + 1 >  R[n].first || (p.first+1==R[n].first && p.second < R[n].second)) {
            R[n].first = p.first+1;
            R[n].second=p.second;
        }
    }
    return R[n];

}

Full code here. 希望这会有所帮助。