hnu12519 Travelling Tom 求所有顶点的最短路径(floyd)

本文出自:http://blog.csdn.net/svitter

原题:http://acm.hnu.cn/online/?action=problem&type=show&id=12519&courseid=0


题意:给你一个图,再给你一条路径,问你最小走多少走完这条路径,走的位置可以重复。一开始以为是哈密顿回路,后来发现原来不是。。在这里顺便补充一下回路的知识:

欧拉回路:行遍所有的顶点,所有的边;

哈密顿回路:行遍所有的顶点。

上述回路均不能重复。

行文至此又考虑了一次负边的情况。在走的过程中应该是不会加钱的。。所以测试数据中的-1应该意为不可直接抵达。之前不考虑负边情况的代码也过了。所以应该不是。

再补充负边负环的情况:

负边一般情况下指的是权值为负,例如:走这条路消耗能量,走另一条路增加能量。

负环则是:可以循环的加能量。。

这样问题就简单了。既然可以重复走,那么总体最短就是找局部最短,也是符合floyd动态规划思想的。

#include <iostream>
#include <stdio.h>

//floyd算法用于有向图
using namespace std;

int cost[201][201];
int a[201];
int n;

void floyd()
{
    int i, j, k;
    for(k = 0; k < n; k++)
        for(i = 0; i < n; i++)
            for(j = 0; j < n; j++)
            {
                if(i == j)
                    continue;
                if(cost[i][j] > 0 && cost[k][j] > 0 && cost[i][k] > 0)
                    cost[i][j] = min(cost[i][j], cost[i][k] + cost[k][j]);
                else if(cost[i][j] < 0 && cost[k][j] > 0 && cost[i][k] > 0)
                    cost[i][j] = cost[i][k] + cost[k][j];
                else
                    continue;
            }//end i, j, k
}


void ace()
{
    int t;
    int i, j;
    bool haveway;
    int ans;
    cin >> t;
    while(t--)
    {

        scanf("%d", &n);
        for(i = 0; i < n; i++)
            scanf("%d", &a[i]);
        for(i = 0; i < n; i++)
            for(j = 0; j < n; j++)
            {
                scanf("%d", &cost[i][j]);
            }
        floyd();
        ans = 0;
        haveway = true;
        for(i = 0; i < n - 1; i++)
        {
            int &temp = cost[a[i]][a[i+1]];
            if(temp != -1)
                ans += temp;
            else
            {
                haveway =false;
                break;
            }
        }
        if(haveway)
        {
            int &temp = cost[a[n-1]][a[0]];
            if(temp != -1)
            {
                ans += temp;
                printf("%d\n", ans);

            }
            else
            {
                printf("impossible\n");
            }
        }
        else
            printf("impossible\n");

    }
}
int main()
{
    ace();
    return 0;
}


你可能感兴趣的:(C++,c,动态规划,ACM,图论)