• UVA 10806 Dijkstra, Dijkstra.


    题意:

      从起点走到终点,然后从终点走到起点,其中不能同时走过相同的一条边,问你最小路径长度。先输入终点n,起点为1,接下来输入m,代表有m条边。每条边由起点,终点,长度组成。  

    分析:

      求最小长度,还限定了每条路只能一次,所以可以用网络流来接。长度就是边费用,每条边的流量为1,这样实现了每条边只能走一次。从起点走到终点再从终点走到起点,相当于在起点前连一个外起点,流量为2,。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    const int maxn=110;
    const int INF=1e9;
    int n,m,s,t;
    int inq[maxn];
    int d[maxn],p[maxn],a[maxn];
    int flow,cost;
    struct Edge
    {
        int from,to,cap,flow,cost;
    };
    vector<Edge>edges;
    vector<int>G[maxn];
    void init()
    {
        flow=cost=s=0;
        t=n;
        for(int i=0;i<t+1;i++)
            G[i].clear();
        edges.clear();
    }
    void add(int from,int to,int cap,int cost)
    {
        edges.push_back((Edge){from,to,cap,0,cost});
        edges.push_back((Edge){to,from,0,0,-cost});
        int nc=edges.size();
        G[from].push_back(nc-2);
        G[to].push_back(nc-1);
    }
    bool bell(int& flow,int& cost)
    {
        for(int i=0;i<=t;i++)
            d[i]=INF;
        memset(inq,0,sizeof(inq));
        d[s]=0;
        inq[s]=1;
        p[s]=0;
        a[s]=INF;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            inq[u]=0;
            for(int i=0;i<G[u].size();i++)
            {
                Edge& e=edges[G[u][i]];
                if(e.cap>e.flow&&d[e.to]>d[u]+e.cost)
                {
                    d[e.to]=d[u]+e.cost;
                    p[e.to]=G[u][i];
                    a[e.to]=min(a[u],e.cap-e.flow);
                    if(!inq[e.to])
                    {
                        q.push(e.to);
                        inq[e.to]=1;
                    }
                }
            }
    
        }
        if(d[t]==INF)
            return false;
        flow+=a[t];
        cost+=d[t]*a[t];
        int u=t;
        while(u!=s)
        {
            //cout<<3<<endl;
            edges[p[u]].flow+=a[t];
            edges[p[u]^1].flow-=a[t];
            u=edges[p[u]].from;
        }
        return true;
    }
    int main()
    {
        while(scanf("%d",&n),n)
        {
            scanf("%d",&m);
            init();
            int a,b,c;
            add(0,1,2,0);
            while(m--)
            {
                scanf("%d%d%d",&a,&b,&c);
                add(a,b,1,c);
                add(b,a,1,c);
            }
            //cout<<1<<endl;
            while(bell(flow,cost));
            //cout<<2<<endl;
            if(flow<2)
                printf("Back to jail
    ");
            else
                printf("%d
    ",cost);
        }
    }

    输入:

    2

    1

    1 2 999

    3

    3

    1 3 10

    2 1 20

    3 2 50

    9

    12

    1 2 10

    1 3 10

    1 4 10

    2 5 10

    3 5 10

    4 5 10

    5 7 10

    6 7 10

    7 8 10

    6 9 10

    7 9 10

    8 9 10

    0

    输出:

    Back to jail

    80

    Back to jail

  • 相关阅读:
    [nginx]简单内容管理系统的spring项目的nginx.conf配置文件的注释理解
    [日常填坑]部署使用Idea开发的spring框架的多模块项目到服务器
    [日常填坑]centos7.0+版本服务器安装jdk9或者jdk10
    [日常填坑]centos7.0+版本服务器安装mysql
    机器学习实战之kNN算法
    机器学习实战之机器学习主要任务
    模式字符串匹配问题(KMP算法)
    ubuntu 更新引导命令
    ubuntu 14.04 中找不到 libgtk-x11-2.0.so
    maven project 更新总是jre-1.5
  • 原文地址:https://www.cnblogs.com/137033036-wjl/p/5761670.html
Copyright © 2020-2023  润新知