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

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 Little Tom wants to make several cyclic tours, which satisfy that, each cycle contain at least two cities, and each city belongs to one cycle exactly. Tom
wants the total length of all the tours minimum, but he is too lazy to calculate. Can you help him?

Input

There are several test cases in the input. You should process to the end of file (EOF).

The first line of each test case contains two integers N (N ≤ 100) and M, indicating the number of cities and the number of roads. The M lines followed, each of them contains three numbers A, B, and C, indicating that there is a road from city A to city B,
whose length is C. (1 ≤ A,B ≤ N, A ≠ B, 1 ≤ C ≤ 1000).

Output

Output one number for each test case, indicating the minimum length of all the tours. If there are no such tours, output -1.

Sample Input

6 9
1 2 5
2 3 5
3 1 10
3 4 12
4 1 8
4 6 11
5 4 7
5 6 9
6 5 4
6 5
1 2 1
2 3 1
3 4 1
4 5 1
5 6 1

Sample Output

42
-1

Hint

 In the first sample, there are two cycles, (1->2->3->1) and (6->5->4->6) whose length is 20 + 22 = 42. 

和HDU 3488同类型的题,具体的解析请看 :HDU3488

水一遍熟悉熟悉模板。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#define INF 0x3f3f3f3f
#define maxn 500
#define maxm 77000
using namespace std;
int n, m;
int outset;
int inset;
struct node {
    int u, v, cap, flow, cost, next;
};

node edge[maxm];
int head[maxn], cnt;
int per[maxn];//记录增广路径上 到达点i的边的编号
int dist[maxn], vis[maxn];

void init(){
    cnt = 0;
    memset(head, -1, sizeof(head));
}

void add(int u, int v, int w, int c){
    int i;
    for(i = head[u]; i != -1; i = edge[i].next){
        node E = edge[i];
        if(v == E.v)
            break;
    }
    if(i != -1){
        if(edge[i].cost > c)
            edge[i].cost = c, edge[i ^ 1].cost = -c;
        return ;
    }
    //edge[cnt] = {u, v, w, 0, c, head[u]}这样写就直接超时了。
    node E1 = {u, v, w, 0, c, head[u]};
    edge[cnt] = E1;
    head[u] = cnt++;
    node E2 = {v, u, 0, 0, -c, head[v]};
    edge[cnt] = E2;
    head[v] = cnt++;
}

void getmap(){
    outset = 0;
    inset = n * 2 + 1;
    for(int i = 1; i <= n; ++i){
        add(outset, i, 1, 0);
        add(i + n, inset, 1, 0);
    }
    while(m--){
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b + n, 1, c);
    }
}

bool SPFA(int st, int ed){
    queue<int>q;
    for(int i = 0; i <= inset; ++i){
        dist[i] = INF;
        vis[i] = 0;
        per[i] = -1;
    }
    dist[st] = 0;
    vis[st] = 1;
    q.push(st);
    while(!q.empty()){
        int u = q.front();
        q.pop();
        vis[u] = 0;
        for(int i = head[u]; i != -1; i = edge[i].next){
            node E = edge[i];
            if(dist[E.v] > dist[u] + E.cost && E.cap > E.flow){//可以松弛 且 没有满流
                dist[E.v] = dist[u] + E.cost;
                per[E.v] = i;//记录到达这个点的边的编号
                if(!vis[E.v]){
                    vis[E.v] = 1;
                    q.push(E.v);
                }
            }
        }
    }
    return per[ed] != -1;
}

void MCMF(int st, int ed, int &cost, int &flow){
    flow = 0;//总流量
    cost = 0;//总费用
    while(SPFA(st, ed)){//每次寻找花销最小的路径
        int mins = INF;
        for(int i = per[ed]; i != -1; i = per[edge[i ^ 1].v]){
            mins = min(mins, edge[i].cap - edge[i].flow);
        }
         //增广
        for(int i = per[ed]; i != -1; i = per[edge[i ^ 1].v]){
            edge[i].flow += mins;
            edge[i ^ 1].flow -= mins;
            cost += edge[i].cost * mins;
        }
        flow += mins;
    }
}
int main (){
    while(scanf("%d%d", &n, &m) != EOF){
        init();
        getmap();
        int cost, flow;
        MCMF(outset, inset, cost, flow);
        if(flow == n)
            printf("%d\n", cost);
        else
            printf("-1\n");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-21 07:51:14

HDU 1853--Cyclic Tour【最小费用最大流 && 有向环最小权值覆盖 】的相关文章

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

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

HDU 1853 Cyclic Tour(KM完美匹配)

HDU 1853 Cyclic Tour 题目链接 题意:一个有向图,边有权值,求把这个图分成几个环,每个点只能属于一个环,使得所有环的权值总和最小,求这个总和 思路:KM完美匹配,由于是环,所以每个点出度入度都是1,一个点拆成两个点,出点和入点,每个点只能用一次,这样就满足了二分图匹配,然后用KM完美匹配去就最小权值的匹配即可 代码: #include <cstdio> #include <cstring> #include <cmath> #include <

hdu 1853 Cyclic Tour &amp;&amp; hdu 3435 A new Graph Game(简单KM算法)

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

hdu 1853 Cyclic Tour 最小费用最大流

题意:一个有向图,现在问将图中的每一个点都划分到一个环中的最少代价(边权和). 思路:拆点,建二分图,跑最小费用最大流即可.若最大流为n,则说明是最大匹配为n,所有点都参与,每个点的入度和出度又是1,所以就是环. /********************************************************* file name: hdu1853.cpp author : kereo create time: 2015年02月16日 星期一 17时38分51秒 *******

hdu 1853 Cyclic Tour 最大权值匹配 全部点连成环的最小边权和

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1904    Accepted Submission(s): 951 Problem Description There are N cities in our c

hdu 1853 Cyclic Tour 最大权值匹配 所有点连成环的最小边权和

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1853 Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1904    Accepted Submission(s): 951 Problem Description There are N cities in our c

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

luogu p4015(最小费用最大流)

传送门 题意: 有\(m\)个仓库和\(n\)个零售商,第\(i\)个仓库送到第\(j\)个零售商需要花费\(v[i][j]\)元.现在需要让仓库的供给量以及零售商的收获量相同,问最小花费以及最大花费. 分析: 相当经典的最小费用最大流的模型.因为要保证供给以及收获相同,即代表着流量平衡,因此我们可以让超级源点\(sp\)跟对应的仓库连一条流量为\(a_i\),费用为\(0\)的边,同时让对应的零售商跟超级汇点\(ep\)连一条流量为\(b_i\),费用为\(0\)的边.而对于仓库与零售商,我们

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