UVA-10806 Dijkstra, Dijkstra. (最小费用流,网络流建模)

题目大意:给一张带权线图,找出一条经过起点s和终点t的最小回路。

题目分析:建立网络,以s为源点,t为汇点,另每条边的容量为1,单位费用为边权值。求最小费用流,增广两次后的最小费用便是答案。

代码如下:

# include<iostream>
# include<cstdio>
# include<cmath>
# include<string>
# include<vector>
# include<list>
# include<set>
# include<map>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;

# define LL long long
# define REP(i,s,n) for(int i=s;i<n;++i)
# define CL(a,b) memset(a,b,sizeof(a))
# define CLL(a,b,n) fill(a,a+n,b)

const double inf=1e30;
const int INF=1<<30;
const int N=105;

struct Edge
{
    int fr,to,cap,flow,cost;
    Edge(int _fr,int _to,int _cap,int _flow,int _cost):fr(_fr),to(_to),cap(_cap),flow(_flow),cost(_cost){}
};
vector<Edge>edges;
vector<int>G[N];
int p[N],a[N],d[N],inq[N];

void init(int n)
{
    edges.clear();
    REP(i,0,n) G[i].clear();
}

void addEdge(int u,int v,int cost)
{
    edges.push_back(Edge(u,v,1,0,cost));
    edges.push_back(Edge(v,u,0,0,-cost));
    int m=edges.size();
    G[u].push_back(m-2);
    G[v].push_back(m-1);
}

bool BellmanFord(int s,int t,int &flow,int &cost)
{
    CL(inq,0);
    CLL(d,INF,t+1);
    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;
        REP(i,0,G[u].size()){
            Edge &e=edges[G[u][i]];
            if(d[e.to]>d[u]+e.cost&&e.cap>e.flow){
                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]){
                    inq[e.to]=1;
                    q.push(e.to);
                }
            }
        }
    }
    if(d[t]==INF) return false;
    flow+=a[t];
    cost+=a[t]*d[t];
    for(int x=t;x!=s;x=edges[p[x]].fr){
        edges[p[x]].flow+=a[t];
        edges[p[x]^1].flow-=a[t];
    }
    return true;
}

void solve(int s,int t)
{
    int flow=0,cost=0;
    if(!BellmanFord(s,t,flow,cost)) printf("Back to jail\n");
    else{
        if(BellmanFord(s,t,flow,cost)) printf("%d\n",cost);
        else printf("Back to jail\n");
    }
}

int main()
{
    int s,t,n,m,a,b,c;
    while(scanf("%d",&n)&&n)
    {
        s=0,t=n-1;
        init(n);
        scanf("%d",&m);
        while(m--)
        {
            scanf("%d%d%d",&a,&b,&c);
            addEdge(a-1,b-1,c);
            addEdge(b-1,a-1,c);
        }
        solve(s,t);
    }
    return 0;
}

  

时间: 2024-09-29 21:03:26

UVA-10806 Dijkstra, Dijkstra. (最小费用流,网络流建模)的相关文章

UVa 10806 Dijkstra, Dijkstra (最小费用流)

Dijkstra, Dijkstra Dexter: “You don’t understand. I can’t walk... they’ve tied my shoelaces together.” Topper Harley: “A knot. Bastards!” Jim Abrahams and Pat Proft, "Hot Shots! Part Deu Description you are a political prisoner in jail. Things are lo

uva 10806 Dijkstra, Dijkstra. (最小费最大流)

uva 10806 Dijkstra, Dijkstra. 题目大意:你和你的伙伴想要越狱.你的伙伴先去探路,等你的伙伴到火车站后,他会打电话给你(电话是藏在蛋糕里带进来的),然后你就能够跑去火车站了,那里有人接应你. 可是.由于你的伙伴跑去火车站的时候穿的是囚服,所以,他经过的街道都被戒严了,你必须从其它街道跑过去. 假设你能够到达火车站,请输出你和你的伙伴在路上花费的最短时间,假设不能请"Back to jail". 解题思路:最小费最大流.设置一个超级源点连向监狱(起点1), 容

UVALive-3268 Jamie&#39;s Contact Groups (最大流,网络流建模)

题目大意:你的手机通讯录里有n个联系人,m个分组,其中,有的联系人在多个分组里.你的任务是在一些分组里删除一些联系人,使得每个联系人只在一个分组里并且使人数最多的那个分组人数最少.找出人数最多的那个分组中的人数. 题目分析:要求的是最小的最大值,二分枚举这个最小的最大人数x.增加源点s和汇点t,从s向每一个联系人连一条弧,容量为1,表示一个联系人只能在一个分组中:然后对于每个联系人向他所在的分组连一条弧,容量为1,表示在这个分组里最多保存一次该联系人:然后从每个分组向汇点连一条弧,容量为x,表示

UVA 10594 Data Flow (最小费用流)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=116&page=show_problem&problem=1535 Problem F Data Flow Time Limit 5 Seconds   In the latest Lab of IIUC, it requires to send huge amount of data from the local s

网络流建模总结

各大竞赛中不乏有许多网络流建模的题,而对于像我(= =)这样的蒟蒻来说可谓是一道题一种解法,还是”老题随便A,新题永不会“的态度,故开此帖来总结一些网络流建模的模型吧,不断更新. 1.分配问题:顾名思义,将一个集合分解为若干个小集合的题目. 常见套话:"现在我们有一批物资要通过一些道路运往某地...","每一场比赛可以为总比分提供两分,可以是每队一分(平局),或者是2-0(一队胜出)...","一块蛋糕,现在有n个厨师来了,每人可以切几份..."

培训补坑(day4:网络流建模与二分图匹配)

补坑时间到QAQ 好吧今天讲的是网络流建模与二分图匹配... day3的网络流建模好像说的差不多了.(囧) 那就接着补点吧.. 既然昨天讲了建图思想,那今天就讲讲网络流最重要的技巧:拆点. 拆点,顾名思义,就是把一个状态拆成数个点以满足题目要求. 今天主要围绕一个例题来讲:修车.(虽然是丧题,但是却是网络流算法思想实现的典例) ------------------我是分割线------------------ 题目: 同一时刻有位车主带着他们的爱车来到了汽车维修中心.维修中心共有M位技术人员,不

BOI&#39;98 DAY 2 TASK 1 CONFERENCE CALL Dijkstra/Dijkstra+priority_queue/SPFA

BOI'98 DAY 2 TASK 1 CONFERENCE CALL PROBLEM A telecom company would like to offer a three-party conference call service. This service enables three customers to participate in a telephone conversation simultaneously. A customer accesses the interconn

UVA 10806 Dijkstra, Dijkstra.

费用流第一题主要是临街表实现这个算法的问题.这里存下 思路还是比较简单.源点0,汇点N+1.费用为边长.容量为1.(普通边).添加边为2(0-1 N-N+1) 代码 #include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <que

Airport Express UVA - 11374(dijkstra)

Airport Express UVA - 11374 题意:n个点,有m条普通路径,k条高速路径,但是k条只能选一条走.问从s到e最短时间. 如果选a-->b这条高速,那么s-->a和b--->e必然也要是最短路. 于是我们可以先用两次dijkstra预处理出s到各点的最短路和e到各点的最短路,然后枚举k条高速走哪条. 输出路径的时候,可以递归~ 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int in