URAL 1004 Sightseeing Trip

URAL_1004

    可以枚举起点和终点做O(N^2)次dij,也可以用floyd直接求最小环,但是用floyd的效率要高一些。

View Code (Dijkstra)
#include<stdio.h>

#include<string.h>

#define MAXD 110

#define MAXM 20010

#define INF 0x3f3f3f3f

int N, M, D, first[MAXD], next[MAXM], e, v[MAXM], w[MAXM], dis[MAXD];

int tree[4 * MAXD], q[MAXD], res, n, p[MAXD];

void add(int x, int y, int z)

{

    v[e] = y, w[e] = z;

    next[e] = first[x];

    first[x] = e ++;

}

void init()

{

    int i, j, k, x, y, z;

    memset(first, -1, sizeof(first));

    e = 0;

    for(i = 0; i < M; i ++)

    {

        scanf("%d%d%d", &x, &y, &z);

        add(x, y, z), add(y, x, z);

    }

}

void update(int i)

{

    for(; i ^ 1; i >>= 1)

        tree[i >> 1] = dis[tree[i]] <= dis[tree[i ^ 1]] ? tree[i] : tree[i ^ 1];

}

void solve()

{

    int i, j, k, x, y, t, ok, f, S, T;

    for(D = 1; D < N + 2; D <<= 1);

    res = INF;

    for(S = 1; S <= N; S ++)

        for(e = first[S]; e != -1; e = next[e])

        {

            T = v[e];

            memset(tree, 0, sizeof(tree));

            memset(dis, 0x3f, sizeof(dis));

            dis[S] = p[S] = 0;

            for(i = first[S]; i != -1; i = next[i])

                if(v[i] != T)

                {

                    tree[D + v[i]] = v[i];

                    dis[v[i]] = w[i], p[v[i]] = S;

                    update(D + v[i]);

                }

            while(tree[1] != 0)

            {

                x = tree[1];

                if(x == T)

                    break;

                tree[D + x] = 0, update(D + x);

                for(j = first[x]; j != -1; j = next[j])

                {

                    t = dis[x] + w[j], y = v[j];

                    if(t < dis[y])

                    {

                        dis[y] = t, p[y] = x;

                        tree[D + y] = y, update(D + y);

                    }

                }

            }

            if(dis[T] != INF && dis[T] + w[e] < res)

            {

                res = dis[T] + w[e];

                for(i = T, n = 0; i != 0; i = p[i])

                    q[n ++] = i;

            }

        }

    if(res == INF)

        printf("No solution.\n");

    else

    {

        printf("%d", q[0]);

        for(i = 1; i < n; i ++)

            printf(" %d", q[i]);

        printf("\n");

    }

}

int main()

{

    for(;;)

    {

        scanf("%d", &N);

        if(N == -1)

            break;

        scanf("%d", &M);

        init();

        solve();

    }

    return 0;

}
View Code (Floyd)
#include<stdio.h>

#include<string.h>

#define MAXD 110

#define INF 0x3f3f3f3f

int N, M, g[MAXD][MAXD], f[MAXD][MAXD], p[MAXD][MAXD];

int q[MAXD], n;

void init()

{

    int i, j, k, x, y, z;

    memset(f, 0x3f, sizeof(f));

    memset(g, 0x3f, sizeof(g));

    for(i = 0; i < M; i ++)

    {

        scanf("%d%d%d", &x, &y, &z);

        if(z < g[x][y])

            f[x][y] = f[y][x] = g[x][y] = g[y][x] = z, p[x][y] = y, p[y][x] = x;

    }

}

int Min(int x, int y)

{

    return x < y ? x : y;

}

void solve()

{

    int i, j, k, x, ans = INF;

    for(k = 1; k <= N; k ++)

    {

        for(i = 1; i < k; i ++)

            if(g[i][k] < ans)

                for(j = i + 1; j < k; j ++)

                    if(g[k][j] < ans && f[i][j] + g[i][k] + g[k][j] < ans)

                    {

                        ans = f[i][j] + g[i][k] + g[k][j];

                        n = 0, x = i;

                        while(x != j)

                        {

                            q[n ++] = x;

                            x = p[x][j];

                        }

                        q[n ++] = j;

                        q[n ++] = k;

                    }

        for(i = 1; i <= N; i ++)

            for(j = 1; j <= N; j ++)

                if(f[i][k] + f[k][j]  < f[i][j])

                    f[i][j] = f[i][k] + f[k][j], p[i][j] = p[i][k];

    }

    if(ans == INF)

        printf("No solution.\n");

    else

    {

        printf("%d", q[0]);

        for(i = 1; i < n; i ++)

            printf(" %d", q[i]);

        printf("\n");

    }

}

int main()

{

    for(;;)

    {

        scanf("%d", &N);

        if(N == -1)

            break;

        scanf("%d", &M);

        init();

        solve();

    }

    return 0;

}

你可能感兴趣的:(IP)