首页 > 其他分享 >HDU 1853 Cyclic Tour && HDU 3488 Tour 最小费用流

HDU 1853 Cyclic Tour && HDU 3488 Tour 最小费用流

时间:2023-04-26 17:33:14浏览次数:32  
标签:3488 HDU int cap cnt Tour cost head dis


Tour


Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 2490    Accepted Submission(s): 1228


Problem Description


In the kingdom of Henryy, there are N (2 <= N <= 200) cities, with M (M <= 30000) one-way roads connecting them. You are lucky enough to have a chance to have a tour in the kingdom. The route should be designed as: The route should contain one or more loops. (A loop is a route like: A->B->……->P->A.)
Every city should be just in one route.
A loop should have at least two cities. In one route, each city should be visited just once. (The only exception is that the first and the last city should be the same and this city is visited twice.)
The total distance the N roads you have chosen should be minimized.


 



Input


An integer T in the first line indicates the number of the test cases.
In each test case, the first line contains two integers N and M, indicating the number of the cities and the one-way roads. Then M lines followed, each line has three integers U, V and W (0 < W <= 10000), indicating that there is a road from U to V, with the distance of W.
It is guaranteed that at least one valid arrangement of the tour is existed.
A blank line is followed after each test case.


 



Output


For each test case, output a line with exactly one integer, which is the minimum total distance.


 



Sample Input

1
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

 



Sample Output


42

//给你一个N个顶点M条边的带权有向图,要你把该图分成1个或多个不相交的有向环,环中至少有两个顶点,且所有定点都只被一个有向环覆盖.问你该有向环所有权值的总和最小是多少?(保证有解)
//把每个点拆成两个,i和i+n,其中源点和i连边,容量1费用0,i+n和汇点连边,容量1费用0,如果点a和点b有通路时,那么连接a和b+n,费用为边的长度。当流量为n时,则说明图上所有点都被覆盖,套模板即可
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;

const int N = 500;
const int INF = 0x3f3f3f3f;
struct edge
{
    int st, to, cap, cost, next;
}g[N*1000];
int dis[N], head[N], pre[N], mpa[N][N];
int cnt;
bool used[N];

void add_edge(int v, int u, int cap, int cost)
{
    g[cnt].st = v, g[cnt].to = u, g[cnt].cap = cap, g[cnt].cost = cost, g[cnt].next = head[v], head[v] = cnt++;
    g[cnt].st = u, g[cnt].to = v, g[cnt].cap = 0, g[cnt].cost = -cost, g[cnt].next = head[u], head[u] = cnt++;
}
int min_cost_flow(int s, int t, int f)
{
    int res = 0;
    while(f > 0)
    {
        memset(dis, 0x3f, sizeof dis);
        memset(used, 0, sizeof used);
        memset(pre, -1, sizeof pre);
        queue <int> que;
        que.push(s);
        dis[s] = 0;
        used[s] = true;
        while(! que.empty())
        {
            int v = que.front(); que.pop();
            for(int i = head[v]; i != -1; i = g[i].next)
            {
                int u = g[i].to;
                if(g[i].cap > 0 && dis[u] > dis[v] + g[i].cost)
                {
                    dis[u] = dis[v] + g[i].cost;
                    pre[u] = i;
                    if(!used[u])
                    {
                        que.push(u);
                        used[u] = true;
                    }
                }
            }
            used[v] = false;
        }
        if(dis[t] == INF) return -1;
        int d = f;
        for(int i = pre[t]; i != -1; i = pre[g[i].st])
            d = min(d, g[i].cap);
        f -= d;
        res += d * dis[t];
        for(int i = pre[t]; i != -1; i = pre[g[i].st])
            g[i].cap -= d, g[i^1].cap += d;
    }
    return res;
}
int main()
{
    int t, n, m, a, b, c;
    scanf("%d", &t);
    while(t--)
    {
        cnt = 0;
        memset(head, -1, sizeof head);
        memset(mpa, 0x3f, sizeof mpa); //mpa数组用来去重边,不去会T
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i++)
        {
            add_edge(0, i, 1, 0);
            add_edge(i + n, 2 * n + 1, 1, 0);
        }
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d%d", &a, &b, &c);
            mpa[a][b] = min(mpa[a][b], c);
        }
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= n; j++)
                if(mpa[i][j] != INF)
                    add_edge(i, n + j, 1, mpa[i][j]);
        printf("%d\n", min_cost_flow(0, 2 * n + 1, n));
    }
    return 0;
}



标签:3488,HDU,int,cap,cnt,Tour,cost,head,dis
From: https://blog.51cto.com/u_4158567/6228227

相关文章

  • HDU - 5649 线段树+区间二分答案 (好题)
    DZYhasasequencea[1…n].Itisapermutationofintegers1∼n.Nowhewantstoperformtwotypesofoperations:0lr:Sorta[l…r]inincreasingorder.1lr:Sorta[l…r]indecreasingorder.Afterdoingalltheoperations,hewilltellyouapositionk,andask......
  • 多校第六场 1011 hdu 5363Key Set(组合数学)
    题目链接:hdu5363题目大意:给出一个到n的自然数集合,问它有多少个子集,元素之和是偶数。题目分析:首先偶数不会导致集合的和的奇偶性发生变化;奇数会导致集合的和的奇偶性发生变化。我们设奇数m1个,偶数m2个。所以我们可以选取0~m1个偶数,但是只能选取偶数个奇数。那么偶数的方案数就是......
  • hdu 5441 长春区域赛网络赛 1005 Travel(并查集)
    题目链接:hdu5441题目大意:有一个n个点的无向图,给出m条边的边权,给出q次询问,每次给出一个值,求用到所有边权不大于这个值的边的情况下,能够互相到达的点对的个数(自己到自己不算)题目分析:首先我们对于边按照边权从小到大排序,对于询问按照值从小到大排序。枚举每次询问,从前到后扫描边,如果......
  • hdu 5442 长春区域赛网络赛 1006 Favorite Donut(后缀数组)
    题目链接:hdu5442题目大意:给出一个环,每颗珠子有一个甜度,选择第一个珠子和吃的方向,问得到的吃珠子的字符串的字典序最大的,如果有多个,选取位置最靠前的,如果还是多个,选择顺时针吃的。题目分析:-首先构造一个字符串,首先正着按环吃,那么就是字符串正着写两遍,连接在一起;中间用没有出现过的......
  • hdu 5446 长春区域赛网络赛1010 Unknown Treasure(lucas定理+中国剩余定理+移位乘法)
    题目链接:hdu5446题目大意:求出Cmn%M,M=p1⋅p2⋯pk题目分析:首先对于每个质数pi我们,我们可以利用Lucas定理求出Cmn%pi的值,Lucas定理如下:Cmn%p=Cm/pn/p⋅Cm%pn%p%p然后我们可以利用中国剩余定理求取最后答案:M=∏i=1kpi,Mi=M/piCmn%M=∑i=1kCmn%pi⋅Mi⋅inv[Mi]因为做乘法......
  • hdu 5444 长春区域赛网络赛 1008 Elven Postman(模拟)
    题目链接:hdu5444题目大意:给出一个序列,这个序列的第一个点是树的根节点,每次操作从当前点走到当前最靠右的每走过的点(点的序号越小越靠右),问将物品从根送到某个点的行进路线.题目分析:个人认为难在题意。。。构造出这个树之后,直接从目的地走回根节点就可以得到要求的路径。然后如何构......
  • HDU 5389 Zero Escape(DP + 滚动数组)
    ZeroEscapeTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:131072/131072K(Java/Others)TotalSubmission(s):864    AcceptedSubmission(s):438ProblemDescriptionZeroEscape,isavisualnoveladventurevideogamedirectedbyKotar......
  • HDU1873 看病要排队
    E- 看病要排队TimeLimit:1000MS     MemoryLimit:32768KB     64bitIOFormat:%I64d&%I64uDescription看病要排队这个是地球人都知道的常识。不过经过细心的0068的观察,他发现了医院里排队还是有讲究的。0068所去的医院有三个医生(汗,这么......
  • HDU 1114 Piggy-Bank
    F- Piggy-BankTimeLimit:1000MS     MemoryLimit:32768KB     64bitIOFormat:%I64d&%I64uSubmit StatusDescriptionBeforeACMcandoanything,abudgetmustbepreparedandthenecessaryfinancialsupportobtained.Themaininc......
  • HDU 1869 六度分离
    六度分离TimeLimit:1000MS     MemoryLimit:32768KB     64bitIOFormat:%I64d&%I64uSubmit Status Practice HDU1869Description1967年,美国著名的社会学家斯坦利・米尔格兰姆提出了一个名为“小世界现象(smallworldphenom......