Cod sursa(job #2083968)

Utilizator gapdanPopescu George gapdan Data 8 decembrie 2017 13:39:24
Problema Floyd-Warshall/Roy-Floyd Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.92 kb
#include <fstream>
#include <vector>
#include <queue>

#define MAXN 101

using namespace std;

ifstream f("royfloyd.in");
ofstream g("royfloyd.out");
int D[MAXN][MAXN];

struct muchie{
    int x;
    int cost;
    muchie(int x, int cost) {
        this->x = x;
        this->cost = cost;
    }
};
int n;
vector<vector<muchie> >v;
void citire() {
    int x, cost;
    f>>n;
    v.resize(n + 1);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            f >> x;
            if (i != j) {
                muchie m = muchie(j, x);
                v[i].push_back(m);
            }
        }
    }
}

void afisare() {
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            g << D[i][j] << " ";
        }
        g<<"\n";
    }
}

void addZero() {
    for (int i = 1; i <= n; ++i) {
        v[0].push_back(muchie(i, 0));
    }
}

int viz[MAXN], d[MAXN];
queue<int>q;
int nr[MAXN];

void bellmanFord(int node) {
    for(int i = 1; i <= n; ++i) {
        d[i] = INT32_MAX;
    }
    viz[node] = 1;d[node] = 0;
    q.push(node);
    bool e = 0;
    while(!q.empty())
    {
        int x = q.front();
        viz[x] = 0;
        q.pop();
        for(int i = 0; i < v[x].size(); ++i)
        {
            int fiu = v[x][i].x;
            int c = v[x][i].cost;
            if(d[fiu] > d[x] + c)
            {
                d[fiu] = d[x] + c;
                if(viz[fiu] == 0)
                {
                    if(nr[fiu] >n)  e=1;
                    else
                    {
                        q.push(fiu);
                        viz[fiu]=1;
                        ++nr[fiu];
                    }
                }
            }
        }
    }
    if(e == 1) {
        throw string{"Ciclu negativ"};
    }
}

void dijkstra(int node) {
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int, int> > >q;
    for(int i = 0; i <= n;++i) d[i]=INT32_MAX;
    d[node] = 0;
    q.push({0, node});
    while(!q.empty())
    {
        int x = q.top().second;
        int cur_d = q.top().first;
        q.pop();
        if (d[x] < cur_d) continue;
        for (int i = 0; i < v[x].size(); ++i)
        {
            int u = v[x][i].x;
            int w = v[x][i].cost;
            if (d[u] > d[x] + w)
            {
                d[u] = d[x] + w;
                q.push({d[u], u});
            }
        }
    }
}

void actualizareMuc() {
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j < v[i].size(); ++j) {
            v[i][j].cost = v[i][j].cost + d[i] - d[j];
        }
    }
}

void johnson() {
    addZero();
    try {
        bellmanFord(0);
    }catch (string e) {
        g <<"Ciclu negativ";
        throw e;
    }
    actualizareMuc();
    for (int i = 1; i <= n; ++i) {
        dijkstra(i);
        for (int j = 1; j <= n; ++j) {
            if (d[j] != INT32_MAX) {
                D[i][j] = d[j];
            }
        }
    }
}


int main() {
    citire();
    johnson();
    afisare();
}