TIMETRIP 잘못된 알고리즘으로 정답처리 된거 같아 질문드립니다.

  • sonyy789
    sonyy789

    벨만-포드 알고리즘에서 최종 경로를 구하는 과정에서
    음수 사이클이 있을 경우, path가 시작점으로 돌아가지 않고,
    음수 사이클에서 순회하게 된다는 사실을 이용해서 코드를 제작했습니다.
    하지만, 벨만포드 for문 횟수 안에서 path가 반드시 음수사이클을 지정한다는 것에 의문이 생겨서, 다음 <테스트 케이스>에서 잘못된 결과가 나왔습니다.
    <테스트 케이스>
    11 12
    0 10 1000
    10 9 1000
    9 8 1000
    8 7 1000
    7 6 1000
    6 5 1000
    5 4 1000
    4 3 1000
    3 2 1
    2 3 -2
    2 0 1000
    0 1 4
    0 - > 10으로가는 경로에 음수사이클이 있어서, INFINITY가 나와야 할것 같은데, 결과는 4 입니다.
    코드는 다음입니다.

    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <limits>
    using namespace std;
    const int inf = numeric_limits<int>::max();
    vector<vector<pair<int, int>>> adj;
    int cycle_chk(vector<int> &set)
    {
        if(set[0] != -1) return 1;
        int count = 1;
        int limit = set.size();
        int here = 1;
        while(1)
        {
            if(set[here] == here) return 1;
            here = set[here];
            if(here == 0) return 0;
            count++;
            if(count > limit) return 1;
        }
    }
    int bellanford(int start, int flags)
    {
        int size = adj.size();
        bool updated;
        vector<int> upper(size, inf);
        vector<int> path(size, -1);
        upper[start] = 0;
        for(int cnt = 0; cnt < size-1; cnt++)
        {
            updated = false;
            for(int here = 0; here < size; here++)
            {
                if(upper[here] == inf) continue;
                for(int i = 0; i < adj[here].size(); i++)
                {
                    int there = adj[here][i].first;
                    int cost = adj[here][i].second;
                    int temp = upper[here] + cost; 
                    if(upper[there] > temp )
                    {
                        updated = true;
                        upper[there] = temp;
                        path[there] = here;
                    }
                }
            }
            if(!updated) break;
        }
        if(upper[1] == inf)
        {
            printf("UNREACHABLE");
            return 1;
        }
        if(updated)
        {
            if(cycle_chk(path))
            {
                printf("INFINITY ");
                return 0;
            }
        }
        if(flags) upper[1] = -upper[1];
        printf("%d ", upper[1]);
        return 0;
    }
    
    int main()
    {
        int c, v, w, a, b, d;
        scanf("%d", &c);
        while(c--)
        {
            scanf("%d%d", &v, &w);
            adj.clear();
            adj = vector<vector<pair<int, int>>>(v);
            for(int i = 0; i < w; i++)
            {
                scanf("%d%d%d", &a, &b, &d);
                adj[a].push_back(make_pair(b,d));
            }
            for(int i = 0; i < 2; i++)
            {
                if(bellanford(0, i)) break;
                for(int here = 0; here < v; here++)
                    for(int k = 0; k < adj[here].size(); k++)
                        adj[here][k].second= -adj[here][k].second;
            }
            printf("\n");
        }
    }
    

    8년 전
0개의 댓글이 있습니다.
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.