[Dijkstra算法]-poj 3268正反两次最短路(矩阵转置)

题目来源:poj 3268 Silver Cow Party

思路:

本来考虑去的时候想用多次调用Dijkstra,求不同地方到party地点的最短距离。看了别人的思路,,可以将距离矩阵转置这样源和终点互换了,可以只调用一次Dijkstra了。再求从party地点回来,也只需要调用一次Dijkstra。

#include 
#include 
#include 
using namespace std;
const int maxn = 1010;
const int INF = 0x3ffffff;
int G[maxn][maxn];
bool vis[maxn] = {false};
int N, M, S;

void Dijkstra(int s, int dis[])
{
    fill(vis, vis + maxn, false);
    dis[s] = 0;
    for (int i = 1; i <= N; i++) //循环n次
    {
        int u = -1; //使d[u]最小且还没有被访问的结点
        int min = INF;
        for (int j = 1; j <= N; j++)
        {
            if (vis[j] == false && dis[j] < min)
            {
                u = j;
                min = dis[j];
            }
        }
        if (u == -1)
        {
            break;
        }
        vis[u] = true;
        for (int i = 1; i <= N; i++)
        {
            if (vis[i] == false && G[u][i] != INF && dis[i] > dis[u] + G[u][i])
            {
                dis[i] = dis[u] + G[u][i];
            }
        }
    }
}

void trans()
{
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j < i; j++)
        {
            swap(G[i][j], G[j][i]);
        }
    }
}

int main()
{
    cin >> N >> M >> S;
    int dis[maxn];
    int dis1[maxn];
    fill(G[0], G[0] + maxn * maxn, INF);
    fill(dis, dis + maxn, INF);
    fill(dis1, dis1 + maxn, INF);
    for (int i = 1; i <= M; i++)
    {
        int u, v, w;
        cin >> u >> v >> w;
        G[u][v] = w;
    }
    Dijkstra(S, dis);
    trans();
    Dijkstra(S, dis1);
    for (int i = 1; i <= N; i++)
    {
        dis[i] += dis1[i];
    }

    int ans = 0;
    for (int i = 1; i <= N; i++)
    {
        if (ans < dis[i])
        {
            ans = dis[i];
        }
    }
    cout << ans << endl;
    return 0;
}

你可能感兴趣的:(图论)