/*
Problem description:
in a directed graph with N nodes, starting from node 1 to i (i=2, 3, ..., N) and back to 1,
(assume that going from node 1 to i needs time = weight(node 1, node i))
count the minimum time needed.
Solution:
calculate the shortest paths from
1: from 1 to i (i=2, 3, ..., n)
2: from i to 1 (i=2, 3, ..., n)
for 1, just use Dijktra
for 2, just reverse the graph and transform it into situation 1
*/
#include<stdio.h>
#include<vector>
#include<queue>
using namespace std;
#define MAX 100011
struct node{ // the node of graph
int num; // the number of current node
int dist; // the distance of previous node to current node
};
struct cmp{// for maintaining a minimum stack
bool operator()(node x, node y){
return x.dist > y.dist ? true : false;
}
};
priority_queue<node, vector<node>, cmp> myQueue; // use for dijkstra algorithm to maitain the nodes to be expanded
vector<node> vList01[MAX]; // use linkedlist to store a graph
vector<node> vList02[MAX]; // store a reversed graph
int time = 0;
int dist[MAX]; // dist[i] means the distance from star -> i
int vist[MAX]; // vist[i] means whether No.i node was visted
/*
Dijkstra's algorithm
*/
void dijkstra(vector<node> vList[MAX], int n){
int i;
for(i=1; i<=n; i++){ // init flag
dist[i] = INT_MAX;
vist[i] = 0;
}
node start; // start node
start.num = 1;
start.dist = 0;
dist[1] = 0;
myQueue.push(start);
while(!myQueue.empty()){// expand until all nodes were added
node v = myQueue.top();
myQueue.pop();
if(vist[v.num] == 1) continue;
vist[v.num] = 1;
int len = vList[v.num].size();
for(i=0; i<len; i++){
node next = vList[v.num][i]; // neighbouring nodes
if(dist[v.num]+next.dist < dist[next.num]){ // relax node
dist[next.num] = dist[v.num]+next.dist;
next.dist = dist[next.num];
myQueue.push(next);// add node to be expand
}
}
}
for(i=1; i<=n; i++){ // count the time
time += dist[i];
//printf("1->%d = %d\n", i, dist[i]);
}
}
int main(){
int ti, ni, mi;
int t, n, m;
scanf("%d", &t);
for(ti=0; ti<t; ti++){
scanf("%d %d", &n, &m);
for(mi=0; mi<m; mi++){
int x, y, w;
scanf("%d %d %d", &x, &y, &w);
// build a normal graph
node v;
v.num = y;
v.dist = w;
vList01[x].push_back(v);
// build a reversed graph
node u;
u.num = x;
u.dist = w;
vList02[y].push_back(u);
}
// sovle
time = 0;
dijkstra(vList01, n);
dijkstra(vList02, n);
//clear graph
for(ni=1; ni<=n; ni++){
vList01[ni].clear();
vList02[ni].clear();
}
printf("%d\n", time);
}
return 0;
}
Review Dijkstra's algorithm and practice my English
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.