1. 程式人生 > >整合:圖論存圖方法及三種重要做法分析(Kruskal Dijkstra Bellman-Ford)

整合:圖論存圖方法及三種重要做法分析(Kruskal Dijkstra Bellman-Ford)

#include <stdio.h> //定義輸入/輸出函式
#include <limits.h> //定義各種資料型別最值常量
#include <math.h> //定義數學函式
#include <stdlib.h> //定義雜項函式及記憶體分配函式
#include <string.h> //字串處理
#include <algorithm>//演算法
#include <queue>//佇列
#include <stack>//棧
const int INF = 0x3f3f3f3f;
using namespace std;
struct node{
    int to, cost;
    int next;
};
node e[2][1000005];
int N, P, Q;
int adj[2][1000005], d[1000005];
bool vis[1000005];
int a, b, c;
long long sum;
void spfa(int k)
{
    memset(vis, 0, sizeof(vis));
    memset(d, INF, sizeof(d));
    stack <int> s; 
    //開queue 也行,一樣時間與記憶體
    s.push(1);
    d[1] = 0;
    vis[1] = 1;
    while (!s.empty()){
        int pos = s.top();
        s.pop();
        vis[pos] = 0;
        for (int i = adj[k][pos]; i!= -1; i = e[k][i].next){
            int to = e[k][i].to;
            int cost = e[k][i].cost;
            if (d[to] > d[pos] + cost){
                d[to] = d[pos] + cost;
                if (vis[to] == 0){
                    s.push(to);
                    vis[to] = 1;
                }
            }
        }
    }
}

int main()
{
    while (scanf("%d", &N) != EOF){
        while (N--){
            memset(adj, -1, sizeof(adj));
            memset(e, 0, sizeof(e));
            sum = 0;
            scanf("%d%d", &P, &Q);
            for (int i = 0; i < Q; i++){
                scanf("%d%d%d", &a, &b, &c);
                e[0][i].to = b;
                e[0][i].cost = c;
                e[0][i].next = adj[0][a];
                adj[0][a] = i;
                e[1][i].to = a;
                e[1][i].cost = c;
                e[1][i].next = adj[1][b];
                adj[1][b] = i;
            }
            
            spfa(0);
            for (int i = 1; i <= P; i++) sum += d[i];
            //printf("\n");
            spfa(1);
            for (int i = 1; i <= P; i++) sum += d[i];
            //printf("\n");
            printf("%lld\n", sum);
        }
    }
}