zoukankan      html  css  js  c++  java
  • hdu 3488 Tour

    http://acm.hdu.edu.cn/showproblem.php?pid=3488

    题意:

    把有向图分成不相交的有向环. 且所有点都只被一个有向环覆盖.

    有向环所有权值的总和最小是多少

    点i拆为i和i+n

    源点向i连流量为1,费用为0的边

    i+n向汇点连流量为1,费用为0的边

    存在有向边i-->j

    i向j+n连流量为1,费用为边权的边

    最大流保证了每个点用了且仅用一次

    n个点,入度与出度均为1,保证了全是环

    最小费用流保证比边权和最小

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define N 403
    #define M 30401
    
    const int inf=2e9;
    
    int cost;
    
    int tot;
    int front[N],to[M<<1],nxt[M<<1],from[M<<1];
    int val[M<<1],cap[M<<1];
    
    int dis[N];
    bool vis[N];
    
    int src,decc;
    
    void read(int &x)
    {
        x=0; char c=getchar();
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); }
    }
    
    void add(int u,int v,int w,int f)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot; from[tot]=u; cap[tot]=w; val[tot]=f;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot; from[tot]=v; cap[tot]=0; val[tot]=-f;
    }
    
    int augment(int now,int flow)
    {
        vis[now]=true;
        if(now==decc) 
        {
            cost-=dis[src]*flow;
            return flow;
        }
        int delta;
        for(int i=front[now];i;i=nxt[i])
        {
            if(cap[i] && !vis[to[i]] && dis[to[i]]==dis[now]+val[i])
            {
                delta=augment(to[i],min(flow,cap[i]));
                if(delta)
                {
                    cap[i]-=delta;
                    cap[i^1]+=delta;
                    return delta;
                }
            }
        }
        return 0;
    }
    
    bool retreat()
    {
        if(vis[decc]) return true;
        int mi=inf;
        for(int i=2;i<=tot;++i)
            if(cap[i] && vis[from[i]] && !vis[to[i]]) 
                mi=min(mi,dis[from[i]]+val[i]-dis[to[i]]);
        if(mi==inf) return false;
        for(int i=src;i<=decc;++i)
            if(vis[i]) dis[i]-=mi;
        return true;
    }
    
    void zkw()
    {
        cost=0;
        memset(dis,0,sizeof(dis));
        do
        {
            memset(vis,false,sizeof(vis));
            augment(src,inf);
        }while(retreat());
        cout<<cost<<'
    ';
    }
    
    int main()
    {
        int T;
        read(T);
        int n,m;
        int u,v,w;
        while(T--)
        {
            tot=1;
            memset(front,0,sizeof(front));
            read(n);
            read(m);
            decc=n*2+1;
            for(int i=1;i<=n;++i) add(src,i,1,0);
            for(int i=1;i<=n;++i) add(i+n,decc,1,0);
            while(m--)
            {
                read(u);
                read(v);
                read(w);
                add(u,v+n,1,w);
            }
            zkw();
        }
    }

    Tour

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


    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
  • 相关阅读:
    C# 杂项
    C# 数组
    我的博客第一天
    Java使用多线程异步执行批量更新操作
    Python爬取百度图片
    以友盟+U-Push为例,深度解读消息推送的筛选架构解决方案应用与实践
    python自动化办公之爬取HTML图片写入PPT实战
    理解Python闭包,这应该是最好的例子
    爬取b站《守护解放西》弹幕
    爬取b站《守护解放西》弹幕
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8082722.html
Copyright © 2011-2022 走看看