HDU - 4370(SPFA+转化思想)

版权声明:本文为博主原创文章,转载请附上源地址。 https://blog.csdn.net/Ema1997/article/details/79785521

最开始的时候,以为只要使第一行和第n列相应的X为1即可,后来看题解发现没有那么简单。其他的大大就把这道题当成了一道图论题来做。所输入的矩阵相当于一个邻接表矩阵,题目的条件的意思大概就是,1的出度为1,n的入度为1,其他点的出度和入度相等。而所要求的就是满足条件的路径的长度。而满足条件的路径有两种。
1.从1到n的路径
2.从1经过其他点形成的闭环与从n开始经过其他点所形成的闭环之和。
接下来就是很简单的实现了。我用的是SPFA,然后求闭环的时候,只用变化一点就好了。意思大概就是,求出源点到所有点的最短路后,将最短路加上这个点到源点的边,就形成了一个经过源点的闭环,而所有闭环中最短的那个,就是所要求的闭环。(和kuangbin大佬的方式不大一样,而且我觉得我自己的方法比较好理解一点,毕竟不用改SPFA。哈哈哈哈哈,这样说真的好掉人品啊。皮这一下很开心)

for (int i = 1; i <= n; i++) {
        if (i == u) continue;
        if (c > dis[i] + cost[i][u]) {
            c = dis[i] + cost[i][u];
        }
    }

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>

using namespace std;

const int INF = 0x3f3f3f3f;
const int maxn = 400;

int n;
int cost[maxn][maxn];
int dis1[maxn];
int dis2[maxn];
int vis[maxn];
int c1, c2;

void Init()
{
    c1 = INF;
    c2 = INF;
    for (int i = 1; i <= n; i++) {
        dis1[i] = INF;
        dis2[i] = INF;
    }
}

int SPFA(int u, int dis[])
{
    memset (vis, 0, sizeof(vis));
    int c = INF;
    dis[u] = 0;
    queue<int> q;
    q.push(u);
    vis[u] = 1;
    while (!q.empty()) {
        int t = q.front();
        q.pop();
        vis[t] = 0;
        for (int i = 1; i <= n; i++) {
            if (i == t) continue;

            if (dis[i] > dis[t] + cost[t][i]) {
                dis[i] = dis[t] + cost[t][i];
                if (!vis[i]) {
                    q.push(i);
                    vis[i] = 1;
                }
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        if (i == u) continue;
        if (c > dis[i] + cost[i][u]) {
            c = dis[i] + cost[i][u];
        }
    }
    return c;
}

int main()
{
    #ifndef ONLINE_JUDGE
    freopen ("in.txt", "r", stdin);
    #endif // ONLINE_JUDGE
    while (scanf ("%d", &n) != EOF) {
        Init ();
        for (int i = 1; i<= n; i++) {
            for (int j = 1; j <= n; j++) {
                scanf ("%d", &cost[i][j]);
            }
        }
        c1 = SPFA (1, dis1);
        c2 = SPFA (n, dis2);
        int c = c1 + c2;
        if (c > dis1[n]) {
            c = dis1[n];
        }
        printf ("%d\n", c);
    }
}

猜你喜欢

转载自blog.csdn.net/Ema1997/article/details/79785521
今日推荐