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

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=3488

    题意:给你一个N个顶点M条边的带权有向图,要你把该图分成1个或多个不相交的有向环.且所有定点都只被一个有向环覆盖.问你该有向环所有权值的总和最小是多少?(哈密顿图)

    题目分类:最小费用最大流

    题目代码

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define INF 1e9
    using namespace std;
    const int maxn=400+5;
    
    struct Edge
    {
        int from,to,cap,flow,cost;
        Edge(){}
        Edge(int f,int t,int c,int fl,int co):from(f),to(t),cap(c),flow(fl),cost(co){}
    };
    
    struct MCMF
    {
        int n,m,s,t;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool inq[maxn];
        int d[maxn];
        int p[maxn];
        int a[maxn];
    
        void init(int n,int s,int t)
        {
            this->n=n, this->s=s, this->t=t;
            edges.clear();
            for(int i=0;i<n;++i) G[i].clear();
        }
    
        void AddEdge(int from,int to,int cap,int cost)
        {
            edges.push_back(Edge(from,to,cap,0,cost));
            edges.push_back(Edge(to,from,0,0,-cost));
            m=edges.size();
            G[from].push_back(m-2);
            G[to].push_back(m-1);
        }
    
        bool BellmanFord(int &flow,int &cost)
        {
            queue<int> Q;
            for(int i=0;i<n;++i) d[i]=INF;
            memset(inq,0,sizeof(inq));
            Q.push(s),inq[s]=true,d[s]=0,a[s]=INF,p[s]=0;
    
            while(!Q.empty())
            {
                int u=Q.front(); Q.pop();
                inq[u]=false;
                for(int i=0;i<G[u].size();++i)
                {
                    Edge &e=edges[G[u][i]];
                    if(e.cap>e.flow && d[e.to]>d[u]+e.cost)
                    {
                        d[e.to]=d[u]+e.cost;
                        a[e.to]=min(a[u],e.cap-e.flow);
                        p[e.to]=G[u][i];
                        if(!inq[e.to]){inq[e.to]=true; Q.push(e.to);}
                    }
                }
            }
            if(d[t]==INF) return false;
            flow += a[t];
            cost += a[t]*d[t];
            int u=t;
            while(u!=s)
            {
                edges[p[u]].flow +=a[t];
                edges[p[u]^1].flow -=a[t];
                u=edges[p[u]].from;
            }
            return true;
        }
    
        int solve(int num)
        {
            int flow=0,cost=0;
            while(BellmanFord(flow,cost));
            return flow==num?cost:-1;
        }
    }MM;
    
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            int src=0,dst=2*n+1;
            MM.init(2*n+2,src,dst);
            for(int i=1;i<=n;++i)
            {
                MM.AddEdge(src,i,1,0);
                MM.AddEdge(i+n,dst,1,0);
            }
            while(m--)
            {
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                MM.AddEdge(u,v+n,1,w);
            }
            printf("%d
    ",MM.solve(n));
        }
        return 0;
    }
    anytime you feel the pain.hey,refrain.don't carry the world upon your shoulders
  • 相关阅读:
    轻松记账方法(A)
    个人学习进度(第八周)
    个人学习进度(第八周)
    Web版四则运算
    个人学习进度(第七周)
    个人学习进度(第六周)
    数组的子数组和最大值
    个人学习进度(第五周)
    个人学习进度(第四周)
    个人学习进度(第三周)
  • 原文地址:https://www.cnblogs.com/gaoss/p/4967111.html
Copyright © 2011-2022 走看看