1. 程式人生 > >SDUT 2143 圖結構練習——最短路徑

SDUT 2143 圖結構練習——最短路徑

//Flyod
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

int Edge[10010][10010];

int main()
{
    int n, m;
    while(cin >> n >> m, n&&m)
    {
        for(int i = 1; i<=n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
             (i == j) ? Edge[i][j] = 0 : Edge[i][j] = INF;
            }
        }
        while(m--)
        {
            int u, v, w;
            cin >> u >> v >> w;
            if(Edge[u][v] > w)
            Edge[u][v] = Edge[v][u] = w;
        }
        for(int k = 1; k <= n; k++)
        {
            for(int i = 1; i <= n; i++)
            {
                if(Edge[i][k] != INF)
                {
                    for(int j = 1; j <= n; j++)
                    {
                        Edge[i][j] = min(Edge[i][k]+Edge[k][j], Edge[i][j]);
                    }
                }
            }
        }
        cout <<  Edge[1][n] << endl;
    }
    return 0;
}

//Dijkstra
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

int Edge[110][110];
int path[110];//路徑記錄(需要時記錄)
int dis[110];
bool vis[110];
int n, m;

void Dijkstra(int st);

int main()
{
    while(cin >> n >> m)
    {
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                (i == j) ? Edge[i][j] = 0 : Edge[i][j] = INF;
            }

        }
        int u, v, w;
        while(m --)
        {
            cin >> u >> v >> w;
            if(Edge[u][v] > w)
            {
                Edge[u][v] = Edge[v][u] = w;
            }
        }
        Dijkstra(1);
    }
    return 0;
}


void Dijkstra(int st)
{

    for(int i = 1; i <= n; i++)
    {
        dis[i] = Edge[st][i];//源點到每個頂點的最短路徑的長度
        if(i != st && dis[i] < INF)
        {
            path[i] = st;
        }
        else
        {
            path[i] = -1;
        }
    }
    vis[st] = 1, dis[st] = 0;
    for(int i = 1; i < n; i++)//從頂點st確定n-1條最短路徑
    {
        int tmp = INF, pos;
        for(int j = 1; j <= n; j++)
        {
            if(!vis[j] && dis[j] < tmp)//選擇具有最短路徑的頂點pos
            {
                tmp = dis[pos = j];
            }
        }
        vis[pos] = 1;
        for(int k = 1; k <= n; k++)//修改剩下未訪問頂點的dis
        {
            if(!vis[k] && Edge[pos][k] < INF && dis[pos]+Edge[pos][k] < dis[k])
            {
            dis[k] = min(dis[k], Edge[pos][k]+dis[pos]);
            path[k] = pos;
            }
        }
    }
    cout << dis[n] << endl;
}


//Bellman-Ford
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

int n, m;
//int path[110];
int Edge[110][110];
int dis[110];

void Bellman_Ford(int st);

int main()
{
    while(cin >> n >> m)
    {
        memset(Edge, INF, sizeof(Edge));
        while(m --)
        {
            int u, v, w;
            cin >> u >> v >> w;
            if(Edge[u][v] > w)
            {
                Edge[u][v] = Edge[v][u] = w;
            }
        }
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                if(i == j)
                {
                    Edge[i][j] = 0;
                }
                else if(Edge[i][j] == 0)
                {
                    Edge[i][j] = INF;
                }
            }
        }
        Bellman_Ford(1);

    }
    return 0;
}


void Bellman_Ford(int st)
{
    for(int i =  1; i <= n; i++)
    {
        dis[i] = Edge[st][i];//初始化經過一條邊的dis[u]的值就是Edge[st][u]
    }
     for(int k = 2; k <= n-1; k++)//經過k條邊到達點u,修改dis(1)[u]遞迴出dis(2)[u],....dis(n-1)[u]
    {//dis(1)[u]表示經過1邊到u的最短距離,...dis(n-1)[u]表示經過n-1條邊到u的最短距離
   //假設a -> c 被 a -> b -> c路徑dis更新後,也許會出現d使得a -> b -> d -> c的距離dis更短
         for(int u = 1; u <= n; u++)//修改每個頂點的dis[u]
        {
            if(u != st)
            {
                for(int j = 1; j <= n; j++)//考慮其他頂點
                {
                    if(Edge[j][u] < INF && dis[j] + Edge[j][u] < dis[u])//頂點j到頂點u有直接路徑,且途徑頂點j可以是的dis[u]縮短
                    {
                        dis[u] = dis[j] + Edge[j][u];
                    }
                }
            }
        }
    }
    cout << dis[n] << endl;
}


//Bellman-Ford優化
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

struct edge
{
  int u, v, w;
}Edge[101000];

int n, m;
int dis[1010];

void Bellman_Ford(int st);

int main()
{
    while(cin >> n >> m)
    {
        memset(Edge, INF, sizeof(Edge));
        for(int i = 1; i <= m; i++)
        {
            int u, v, w;
            cin >> u >> v >> w;
            Edge[i].u = u, Edge[i].v = v , Edge[i].w = w;
            Edge[i+m].u = v, Edge[i+m].v = u , Edge[i+m].w = w;//無向圖
        }
        Bellman_Ford(1);
    }
    return 0;
}


void Bellman_Ford(int st)
{
    for(int i =  1; i <= n; i++)
    {
        dis[i] = INF;
    }
    dis[st] = 0;
    for(int k = 2; k <= n; k++)
    {
        for(int i = 1; i <= 2*m; i++)
        {
        if(dis[Edge[i].u] != INF  &&  dis[Edge[i].u] + Edge[i].w < dis[Edge[i].v])
                        dis[Edge[i].v] = dis[Edge[i].u] + Edge[i].w;
        }
    }
    cout << dis[n] << endl;
}


//SPFA
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;

int Edge[110][110];
int n, m;
int flag, ans;

queue<int > Q;
bool vis[110];
int dis[110];

void SPFA(int st);

int main()
{
    int u, v, w;
    while(~scanf("%d %d", &n, &m))
    {
        memset(Edge, INF, sizeof(Edge));
        while(m --)
        {
            scanf("%d %d %d", &u,  &v,  &w);
            if(Edge[u][v] > w)
            {
              Edge[u][v] = Edge[v][u] = w;
            }
        }
        SPFA(1);
    }
    return 0;
}

void SPFA(int st)
{
    int tmp;
    memset(dis, INF, sizeof(dis));
    memset(vis, 0, sizeof(vis));
    vis[st] = 1, dis[st] = 0;
    Q.push(st);
    while(!Q.empty())
    {
        tmp = Q.front();
        Q.pop();
        vis[tmp] = 0;
        for(int i = 1; i <= n; i++)
        {
          if(Edge[tmp][i] < INF && dis[tmp] + Edge[tmp][i] < dis[i])
          {
            dis[i] = dis[tmp] + Edge[tmp][i];
            if(!vis[i])
            {
              vis[i] = 1;
             Q.push(i);
            }
          }
        }
    }
    printf("%d\n", dis[n]);
}