• poj 2135 Farm Tour 【无向图最小费用最大流】


    题目:poj 2135 Farm Tour 


    题意:给出一个无向图,问从 1 点到 n 点然后又回到一点总共的最短路。


    分析:这个题目不读细致的话可能会当做最短路来做,最短路求出来的不一定是最优的,他是两条分别最短,但不一定是和最短。

    我们能够用费用流来非常轻易的解决,建边容量为1,费用为边权。然后源点s连 1 。费用0 。容量 2 ,n点连接汇点,容量2,费用0,,就能够了。

    注意这个题目是无向图,所以要建双向边。


    AC代码:

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <vector>
    #include <queue>
    #include <cstring>
    using namespace std;
    const int N = 1050;
    const int inf = 0x3f3f3f3f;
    #define Del(a,b) memset(a,b,sizeof(a))
    struct Node
    {
        int from,to,cap,flow,cost;
    };
    vector<int> v[N];
    vector<Node> e;
    void add_Node(int from,int to,int cap,int cost)
    {
        e.push_back((Node){from,to,cap,0,cost});
        e.push_back((Node){to,from,0,0,-cost});
        int len = e.size()-1;
        v[to].push_back(len);
        v[from].push_back(len-1);
    }
    int vis[N],dis[N];
    int father[N],pos[N];
    bool BellManford(int s,int t,int& flow,int& cost)
    {
        Del(dis,inf);
        Del(vis,0);
        queue<int> q;
        q.push(s);
        vis[s]=1;
        father[s]=-1;
        dis[s] = 0;
        pos[s] = inf;
        while(!q.empty())
        {
            int f = q.front();
            q.pop();
            vis[f] = 0;
            for(int i=0; i<v[f].size(); i++)
            {
                Node& tmp = e[v[f][i]];
                if(tmp.cap>tmp.flow && dis[tmp.to] > dis[f] + tmp.cost)
                {
                    dis[tmp.to] = dis[f] + tmp.cost;
                    father[tmp.to] = v[f][i];
                    pos[tmp.to] = min(pos[f],tmp.cap - tmp.flow);
                    if(vis[tmp.to] == 0)
                    {
                        vis[tmp.to]=1;
                        q.push(tmp.to);
                    }
                }
            }
        }
        if(dis[t] == inf)
            return false;
        flow += pos[t];
        cost += dis[t]*pos[t];
        for(int u = t; u!=s ; u = e[father[u]].from)
        {
            e[father[u]].flow += pos[t];
            e[father[u]^1].flow -= pos[t];
        }
        return true;
    }
    int Mincost(int s,int t)
    {
        int flow = 0, cost = 0;
        while(BellManford(s,t,flow,cost)){}
        return cost;
    }
    void Clear(int x)
    {
        for(int i=0; i<=x; i++)
            v[i].clear();
        e.clear();
    }
    
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=0;i<m;i++)
            {
                int x,y,z;
                scanf("%d%d%d",&x,&y,&z);
                add_Node(x,y,1,z);
                add_Node(y,x,1,z);
            }
            int s = 0 ,t = n+1;
            add_Node(s,1,2,0);
            add_Node(n,t,2,0);
            int ans = Mincost(s,t);
            printf("%d
    ",ans);
            Clear(n+1);
        }
        return 0;
    }
    


  • 相关阅读:
    String和enum的互相转换
    LeetCode: Sort Colors
    LeetCode: Subsets II
    LeetCode: Spiral Matrix II
    LeetCode: Subsets
    LeetCode: Sum Root to Leaf Numbers
    LeetCode: Sqrt(x)
    LeetCode: Sudoku Solver
    LeetCode: Spiral Matrix
    LeetCode: Substring with Concatenation of All Words
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/6894751.html
Copyright © 2020-2023  润新知