hdoj 3488 Tour 【经典最小费用最大流】

题目:hdoj 3488 Tour

题意:给出n个点m条边,然后让你求每个点只能在一个环中(哈密顿环),且所有点只走一次的最小费用。

分析:直接画图的话可能没有思路,但是把它化成一个二分图的话肯定瞬间思路来了,每个点只走一次,很好建图

建图方案:

每个点拆成两个i 和 ii

然后s连接所有 i ,容量1 ,费用0

ii 连接所有 t ,容量 1 ,费用0

所有右边的点 xi 连接 yii ,费用为权值,容量0

AC代码:

#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;

#define PB push_back
#define MP make_pair
#define Del(a,b) memset(a,b,sizeof(a))

typedef vector<int> VI;
typedef long long LL;
const LL inf = 0x3f3f3f3f;
const int N = 500;
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))
    {
        //printf("%d\n",cost);
    }
    return cost;
}
void Clear(int x)
{
    for(int i=0; i<=x; i++)
        v[i].clear();
    e.clear();
}
char mp[120][120];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        int s = 0 , t = 1;
        for(int i=1;i<=n;i++)
        {
            add_Node(s,i*2,1,0);
            add_Node(i*2+1,t,1,0);
        }
        for(int i=0;i<m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add_Node(x*2,y*2+1,1,z);
        }
        int ans = Mincost(s,t);
        printf("%d\n",ans);
        Clear(2*n+5);
    }
    return 0;
}
时间: 2024-10-28 11:45:39

hdoj 3488 Tour 【经典最小费用最大流】的相关文章

hdoj 3488 Tour 【最小费用最大流】【KM算法】

Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 2299    Accepted Submission(s): 1151 Problem Description In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 3000

POJ2135Farm Tour(最小费用最大流模板)

题目链接:http://poj.org/problem?id=2135 题意:农场主想从1到n,然后从n到1,每条边最多走一次,不能走重复的路,问最短距离是多少. 建图:取超级源点s,并与房子连一条边,容量为2,费用为0:取barn与超级汇点 t 的边的容量为2,费用为0 房子与barn的费用为距离,容量为1 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring>

poj 2135 Farm Tour (最小费用最大流模板)

网络流的费用: 在实际应用中,与网络流有关的问题,不仅涉及流量,而且还有费用的因素.网络的每一条边(v,w)除了给定容量cap(v,w)外,还定义了一个单位流量费用cost(v,w) 最小费用最大流问题 给定网络G,要求G的一个最大用流flow,使流的总费用最小. 求解MCMF问题的算法: 最小费用最大流最常用和基本的算法我们可以称它为最小费用路算法,其思想与求最大流的增广路算法类似,不断在残流网络中寻找从源s到汇t的最小费用路,即残流网络中从s到t的以费用为权的最短路,然后沿最小费用路增流,直

hdu 3488(KM算法||最小费用最大流)

Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 2925    Accepted Submission(s): 1407 Problem Description In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000

POJ2135 Farm Tour 【最小费用最大流】

Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11782   Accepted: 4393 Description When FJ's friends visit him on the farm, he likes to show them around. His farm comprises N (1 <= N <= 1000) fields numbered 1..N, the first of

POJ 2135 Farm Tour(最小费用最大流,变形)

题意:给一个无向图,FJ要从1号点出发到达n号点,再返回到1号点,但是路一旦走过了就会销毁(即回去不能经过),每条路长度不同,那么完成这趟旅行要走多长的路?(注:会有重边,点号无序,无向图!) 思路: 有重边,要用邻接表.所给的每条边都要变成4条有向边!否则可能一开始就到达不了终点了.最后要再加上一个源点和汇点,容量cap(源点,1)=2,指定只能走两次,再规定其他所给的边的容量是1就行了,当边被走过了,就自动增加了流,也就走不了了. 解释看代码更清晰. 1 //#pragma comment(

HDU 1853--Cyclic Tour【最小费用最大流 &amp;&amp; 有向环最小权值覆盖 】

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1950    Accepted Submission(s): 984 Problem Description There are N cities in our country, and M one-way roads connecting them. Now L

HDU 1853 Cyclic Tour(最小费用最大流)

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1879    Accepted Submission(s): 938 Problem Description There are N cities in our country, and M one-way roads connecting them. Now L

hdoj 2282 Chocolate 【最小费用最大流】

Chocolate Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 565    Accepted Submission(s): 281 Problem Description Lethe loves eating chocolates very much. In Lethe's birthday, her good friend ec