#ifndef DIJKSTRA_H
#define DIJKSTRA_H
#include <math.h>
#include <vector>
#include <climits>
using namespace std;
typedef struct
{
int head;
int tail;
int cost;
} Edge;
void Dijkstra(vector<Edge> &E, vector<vector<int>> &Vtail, int nV, int nE, int s, int *spath);
#endif
#include "dijkstra.h"
int heap[10000];
int prior[10000];
int heapSize = 0;
//int pos2Id[1000];
int id2Pos[10000];
bool boolX[10000];
void InsertHeap(int id)
{
heap[heapSize++] = id;
id2Pos[id] = heapSize-1;
int pos = heapSize-1;
while (pos > 0)
{
int parent = pos-1 >> 1;
if(prior[id] > prior[heap[parent]])
{
break;
}
int temp = heap[parent];
heap[parent] = id;
heap[pos] = temp;
id2Pos[id] = parent;
id2Pos[temp] = pos;
pos = parent;
}
}
void DeleteHeap(int id)
{
int pos = id2Pos[id];
if (pos < 0)
{
return;
}
heap[pos] = heap[--heapSize];
id2Pos[heap[pos]] = pos;
while (pos < (heapSize>>1))
{
int child = 2*pos+1;
if (child+1< heapSize && prior[heap[child+1]] < prior[heap[child]])
{
child++;
}
if (prior[heap[pos]] <= prior[heap[child]])
{
break;
}
int temp = heap[pos];
heap[pos] = heap[child];
heap[child] = temp;
id2Pos[temp] = child;
id2Pos[heap[pos]] = pos;
pos = child;
}
}
int PopMin()
{
int id = heap[0];
heap[0] = heap[--heapSize];
int pos = 0;
id2Pos[heap[pos]] = pos;
while (pos < (heapSize>>1))
{
int child = 2*pos+1;
if (child+1< heapSize && prior[heap[child+1]] < prior[heap[child]])
{
child++;
}
if (prior[heap[pos]] <= prior[heap[child]])
{
break;
}
int temp = heap[pos];
heap[pos] = heap[child];
heap[child] = temp;
id2Pos[temp] = child;
id2Pos[heap[pos]] = pos;
pos = child;
}
return id;
}
void Dijkstra(vector<Edge> &E, vector<vector<int>> &Vtail, int nV, int nE, int s, int *spath)
{
// --------- Initial -------
for (int i=0; i<nV; i++)
{
id2Pos[i] = -1;
prior[i] = INT_MAX;
boolX[i] = false;
}
// -------------------------
prior[s] = 0;
InsertHeap(s);
while(heapSize >0)
{
int u = PopMin();
boolX[u] = true;
for (int i=0; i<Vtail[u].size(); i++)
{
int v = E[Vtail[u][i]].head;
int w = E[Vtail[u][i]].cost;
if (boolX[v])
{
continue;
}
DeleteHeap(v);
prior[v] = min(prior[v], prior[u]+w);
InsertHeap(v);
}
}
for (int i=0; i<nV; i++)
{
spath[i] = prior[i];
}
}
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <climits>
#include "dijkstra.h"
using namespace std;
bool BellmanFordInit(vector<Edge> &E, int nV, int nE, int *pv)
{
// ---------- Initial -------------
int ** A = new int*[2];
for (int i=0; i<2; i++)
A[i] = new int[nV];
for (int j=0; j<nV; j++)
{
A[0][j] = 0;
A[1][j] = INT_MAX;
}
// -----------------------------------
int h;
int t;
int c;
for (int i=1; i<nV+1; i++)
{
if(1 == i%2)
{
for(int j=0; j<nE; j++)
{
h = E[j].head;
t = E[j].tail;
c = E[j].cost;
A[1][h] = min(A[1][h], min(A[0][h], A[0][t]+c));
}
}
else
{
for(int j=0; j<nE; j++)
{
h = E[j].head;
t = E[j].tail;
c = E[j].cost;
A[0][h] = min(A[0][h], min(A[1][h], A[1][t]+c));
}
}
}
// --------- Judge ----------
int sum =0;
for(int j=0; j<nV; j++)
{
pv[j] = A[0][j];
sum += A[1][j] - A[0][j];
}
delete []A;
if(0 == sum)
return true;
else
return false;
}
int RwSDijkstra(vector<Edge> &E, vector<vector<int>> &Vtail, int *pv, int nV, int nE, int s, int *spath)
{
Dijkstra(E, Vtail, nV, nE, s, spath);
int sp = INT_MAX;
for (int i=1; i<nV; i++)
{
if (s != i)
{
sp = min(sp, spath[i]-pv[s]+pv[i]);
}
}
return sp;
}
int main()
{
ifstream infile;
infile.open("g2.txt");
// -------------------------
string line;
stringstream ss;
getline(infile, line);
ss << line;
int nV, nE;
ss >> nV;
ss >> nE;
// --------- Initialize ---------
vector<vector<int>> Vtail(nV);
vector<Edge> E(nE);
// ------------
ss.clear();
line.clear();
int n=0;
while(getline(infile, line) && n<nE)
{
ss << line;
int h;
int t;
int c;
ss >> t;
ss >> h;
ss >> c;
E[n].tail = t-1;
E[n].head = h-1;
E[n].cost = c;
Vtail[t-1].push_back(n);
ss.clear();
line.clear();
n++;
}
infile.close();
// ------- Bellman-Ford ------
int *pv = new int[nV];
if (!BellmanFordInit(E, nV, nE, pv))
{
delete []pv;
cout << "There is neg cycle" << endl;
return -1;
}
// ------- Small cost -----
int sss = INT_MAX;
for (int i=1; i<nE; i++)
{
sss = min(sss, E[i].cost);
}
cout << "Small edge : " << sss << endl;
// ---------- Dijkstra -----------
// Reweight
for (int i=0; i<nE; i++)
{
int t = E[i].tail;
int h = E[i].head;
int c = E[i].cost;
E[i].cost = c + pv[t]-pv[h];
}
// All pair ---
int *spath = new int[nV];
int sp = INT_MAX;
for (int i=0; i<nV; i++)
{
sp = min(sp, RwSDijkstra(E, Vtail, pv, nV, nE, i, spath));
}
cout << "All pair short path : " << sp << endl;
// -----------------
delete[] spath;
delete []pv;
return 0;
}