• hdu 4370


    这个题说实话我没看出来,我看的别人的博客

    https://blog.csdn.net/u013761036/article/details/39377499

    这个人讲的很清楚,可以直接去看他的

    题目给的 3个要求:

    1.X 12+X 13+...X 1n=1 
    2.X 1n+X 2n+...X n-1n=1 
    3.for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n). 

    简单来说就是创建n个点,X 12+X 13+...X 1n=1 代表我们的  1点  的出度是1,这里没有对 1点 的入度做限制,也就是说入度可以为0

                 X 1n+X 2n+...X n-1n=1 代表  n点  的入读是n,同上,出度可以为0

                for each i (1<i<n), satisfies ∑X ki (1<=k<=n)=∑X ij (1<=j<=n).    代表 2 到 (n-1) 这些点的入度等于出度

    仔细想一下最短路,不也是这样吗,中间的点入度等于出度,初始点 入度为 0,结束的点出度为0

    把 c这个矩阵看成任意两点间的距离,把 x 矩阵看成从1到n 最短路所要经过的路径,

    求个最短路就是结果

    当然还有一个特殊情况,就是 1到1的最小环+n到n的最小环,这样做出来也是满足那三个条件的

    另外题目讲了c[i]>=0,不用担心负环

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    using namespace std;
    int arr[305][305];
    int n;
    bool vis[305];
    int dis[305];
    int spfa(int s,int e,int k)
    {
        memset(dis,0x3f,sizeof(dis));
        memset(vis,0,sizeof(vis));
        queue<int> q;
        if(k == 1)
        {
            q.push(s);
            vis[s] = true;
            dis[s] = 0;
        }
        else
        {
            for(int i = 1; i <= n; ++i)
            {
                if(i == s) continue;
                q.push(i);
                vis[i] = true;
                dis[i] = arr[s][i];
            }
        }
        while(!q.empty())
        {
            int u = q.front();
            q.pop();
            vis[u] = false;
            for(int i = 1; i <= n; ++i)
            {
                if(i == u) continue;
                if(dis[i]>dis[u] + arr[u][i])
                {
                    dis[i] = dis[u] + arr[u][i];
                    if(vis[i] == false)
                    {
                        vis[i] = true;
                        q.push(i);
                    }
                }
            }
        }
        return dis[e];
    }
    int main()
    {
        while(scanf("%d",&n) != EOF)
        {
            for(int i = 1; i <= n; ++i)
            {
                for(int j = 1; j <= n; ++j)
                {
                    scanf("%d",&arr[i][j]);
                }
            }
            int s1 = spfa(1,n,1);
            int s2 = spfa(1,1,2);
            int s3 = spfa(n,n,2);
            if(s1 > s2 + s3) s1 = s2 + s3;
            printf("%d
    ",s1);
        }
    }
  • 相关阅读:
    【Jenkins】jenkins 配置腾讯企业邮箱
    Monkey 用户指南(译)
    Windows,easygui 安装
    python笔记:list--pop与remove的区别
    递归--Java_汉诺塔
    appium安装 For windows
    【web开发--js学习】functionName 如果是一个属性值,函数将不会被调用
    python爬取煎蛋网图片
    pv&pvc
    docker
  • 原文地址:https://www.cnblogs.com/mltang/p/9845123.html
Copyright © 2020-2023  润新知