POJ3268

///其实能还短,然后再改吧
#include <iostream>
#define INF 0x1f1f1f1f
#define N 1005
using namespace std;
int map1[N][N], map2[N][N];//建两个图,一个是另一个的转置
int dis1[N], dis2[N];
bool mark1[N], mark2[N];
int n, m, x;

void init()
{
    int i, j;
    for(i = 1; i <= n; ++i)
        {
          for(j = 1; j <= n; ++j)
          {
              map1[i][j] = INF;
              map2[i][j] = INF;
          }
          map1[i][i] = 0;
          map2[i][i] = 0;
        }

}

void dijFirst(int start, int n)
{
    int i, j, mindis, k;
    for(i = 1; i <= n; ++i)
    {
        dis1[i] = map1[start][i];
        mark1[i] = false;
    }
    dis1[start] = 0;
    mark1[start] = true;

    while(1)
    {
        mindis = INF;
        for(j = 1; j <= n; ++j)
        {
            if(!mark1[j] && mindis > dis1[j])
            {
                mindis = dis1[j];
                k = j;
            }
        }
        mark1[k] = true;
        if(mindis == INF)  break;

        for(j = 1; j <= n; ++j)
        {
            if(!mark1[j] && dis1[j] > dis1[k] + map1[k][j])
                dis1[j] = dis1[k] + map1[k][j];
        }
    }
}

void dijSecond(int start, int n)
{
    int i, j, mindis, k;
    for(i = 1; i <= n; ++i)
    {
        dis2[i] = map2[start][i];
        mark2[i] = false;
    }
    dis2[start] = 0;
    mark2[start] = true;

    while(1)
    {
        mindis = INF;
        for(j = 1; j <= n; ++j)
        {
            if(!mark2[j] && mindis > dis2[j])
            {
                mindis = dis2[j];
                k = j;
            }
        }
        mark2[k] = true;
        if(mindis == INF)  break;

        for(j = 1; j <= n; ++j)
        {
            if(!mark2[j] && dis2[j] > dis2[k] + map2[k][j])
                dis2[j] = dis2[k] + map2[k][j];
        }
    }
}

int main()
{
    int i, j;
    while(cin >> n >> m >> x)
    {
        init();
        for(i = 1; i <= m; ++i)
        {
            int u, v ,w;
            cin >> u >> v >> w;
            map2[u][v] = w;
        }

        int max;
        max = 0;
        dijSecond(x, n);
///最关键的地方,将矩阵转置以后,从终节点出发到其他节点的距离,就是反向走有向图
        for(i = 1; i <= n; ++i)
        {
            for(j = 1; j <= n; ++j)
            {
                map1[i][j] = map2[j][i];
            }
        }

        dijFirst(x, n);
        for(i = 1; i <= n; ++i)
        {
            max = (dis1[i] + dis2[i] > max) ? (dis1[i] + dis2[i]) : max;
        }
        cout << max << endl;


    }
    //cout << "Hello world!" << endl;
    return 0;
}

///一开始只是简单的正搜一次,反搜一次,赵最短路,正搜时用到了循环,dijkstar可是///O(N^2)啊,不超时才怪,之后百度了下,说转置以后的图就是正搜用的图,才吧时间降到115MS,还是水平不够!加油!





///第二次写,memory减少将近一半!!!思想还是一样的,
#include <iostream>
#define INF 0x1f1f1f1f
#define MAX_SIZE 1005
using namespace std;

int map[MAX_SIZE][MAX_SIZE];
int dis[MAX_SIZE];
bool mark[MAX_SIZE];

void init(int n)
{
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j <= n; ++j)
            map[i][j] = INF;
        map[i][i] = 0;
    }
}

void dijkstar(int start, int n)
{
    for(int i = 1; i <= n; ++i)
    {
        dis[i] = map[start][i];
        mark[i] = false;
    }

    dis[start] = 0;
    mark[start] = true;

    int mindis, tag;

    while(1)
    {
        mindis = INF;
        for(int i = 1; i <= n; ++i)
        {
            if(!mark[i] && mindis > dis[i])
            {
                mindis = dis[i];
                tag = i;
            }
        }

        mark[tag] = true;

        if(mindis == INF)  break;

        for(int i = 1; i <= n; ++i)
        {
            if(!mark[i] && dis[i] > dis[tag] + map[tag][i])
                dis[i] = dis[tag] + map[tag][i];
        }
    }
}

int main()
{
    ///需要看看以前的代码,所以还是不够熟,加油!!
    int n, m, end;
    while(cin >> n >> m >> end)
    {
        init(n);

        int x, y, w;
        while(m--)
        {
            cin >> x >> y >> w;
            if(map[x][y] > w)
                map[x][y] = w;
        }

        int sum2[MAX_SIZE];
        dijkstar(end, n);
        for(int i = 1; i <= n; ++i)
        {
            sum2[i] = dis[i];
        }

        int temp;
        for(int i = 1; i <= n; ++i)
        {
            for(int j = i + 1; j <= n; ++j)
            {
                    temp = map[i][j];
                    map[i][j] = map[j][i];
                    map[j][i] = temp;
            }
        }

        int sum1[MAX_SIZE];
        dijkstar(end, n);
        for(int i = 1; i <= n; ++i)
        {
            sum1[i] = dis[i];
        }

        int max = -1;
        for(int i = 1; i <= n ; ++i)
        {
            max = (max > sum1[i] + sum2[i]) ? max : sum1[i] + sum2[i];
        }
        cout << max << endl;

    }

    return 0;
}

你可能感兴趣的:(ACM,poj,最短路)