URAL_1004

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

URAL 1004 Sightseeing Trip_#defineURAL 1004 Sightseeing Trip_URAL_02View 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;
}
URAL 1004 Sightseeing Trip_#defineURAL 1004 Sightseeing Trip_URAL_02View 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;
}