• HDU 3488 Tour(最小费用流:有向环最小权值覆盖)


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

    题意:

    给出n个点和m条边,每条边有距离,把这n个点分成1个或多个环,且每个点只能在一个环中,保证有解。

    思路:

    把一个点分成两部分,1~n和n+i~2*n。

    连边的情况是这样的,(src,i,1,0),(i+n,dst,1,0)。

    如果两个点之间相同,则(i,j+n,1,d)。

    其实这道题目就是选n条边,如何使得权值之和最小。

    具体请参考这http://blog.csdn.net/u013480600/article/details/39185013

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cmath>
      4 #include<cstring>
      5 #include<queue>
      6 using namespace std;
      7 typedef long long LL;
      8 
      9 const int maxn=400+5;
     10 const int INF=0x3f3f3f3f;
     11 
     12 struct Edge
     13 {
     14     int from, to, cap, flow, cost;
     15     Edge(int u, int v, int c, int f, int w) :from(u), to(v), cap(c), flow(f), cost(w) {}
     16 };
     17 
     18 struct MCMF
     19 {
     20     int n, m;
     21     vector<Edge> edges;
     22     vector<int> G[maxn];
     23     int inq[maxn];
     24     int d[maxn];
     25     int p[maxn];
     26     int a[maxn];
     27 
     28     void init(int n)
     29     {
     30         this->n = n;
     31         for (int i = 0; i<n; i++) G[i].clear();
     32         edges.clear();
     33     }
     34 
     35     void AddEdge(int from, int to, int cap, int cost)
     36     {
     37         edges.push_back(Edge(from, to, cap, 0, cost));
     38         edges.push_back(Edge(to, from, 0, 0, -cost));
     39         m = edges.size();
     40         G[from].push_back(m - 2);
     41         G[to].push_back(m - 1);
     42     }
     43 
     44     bool BellmanFord(int s, int t, int &flow, LL & cost)
     45     {
     46         for (int i = 0; i<n; i++) d[i] = INF;
     47         memset(inq, 0, sizeof(inq));
     48         d[s] = 0; inq[s] = 1; p[s] = 0; a[s] = INF;
     49 
     50         queue<int> Q;
     51         Q.push(s);
     52         while (!Q.empty()){
     53             int u = Q.front(); Q.pop();
     54             inq[u] = 0;
     55             for (int i = 0; i<G[u].size(); i++){
     56                 Edge& e = edges[G[u][i]];
     57                 if (e.cap>e.flow && d[e.to]>d[u] + e.cost){
     58                     d[e.to] = d[u] + e.cost;
     59                     p[e.to] = G[u][i];
     60                     a[e.to] = min(a[u], e.cap - e.flow);
     61                     if (!inq[e.to]) { Q.push(e.to); inq[e.to] = 1; }
     62                 }
     63             }
     64         }
     65         if (d[t] == INF) return false;
     66         flow += a[t];
     67         cost += (LL)d[t] * (LL)a[t];
     68         for (int u = t; u != s; u = edges[p[u]].from){
     69             edges[p[u]].flow += a[t];
     70             edges[p[u] ^ 1].flow -= a[t];
     71 
     72         }
     73         return true;
     74     }
     75 
     76     void MincostMaxdflow(int s, int t, LL & cost)
     77     {
     78         int flow = 0; cost = 0;
     79         while (BellmanFord(s, t, flow, cost) );
     80         //return flow;
     81     }
     82 }t;
     83 
     84 int n,m;
     85 
     86 int main()
     87 {
     88     //freopen("D:\input.txt", "r", stdin);
     89     int T;
     90     scanf("%d",&T);
     91     int u,v,d;
     92     while(T--)
     93     {
     94         scanf("%d%d",&n,&m);
     95         int src=0,dst=2*n+1;
     96         t.init(dst+1);
     97         for(int i=1;i<=n;i++)
     98         {
     99             t.AddEdge(src,i,1,0);
    100             t.AddEdge(i+n,dst,1,0);
    101         }
    102         for(int i=0;i<m;i++)
    103         {
    104             scanf("%d%d%d",&u,&v,&d);
    105             t.AddEdge(u,v+n,1,d);
    106         }
    107         long long cost;
    108         t.MincostMaxdflow(src,dst,cost);
    109         printf("%d
    ",cost);
    110     }
    111     return 0;
    112 }
  • 相关阅读:
    bzoj3687
    bzoj1930
    splay启发式合并
    学习笔记::启发式合并
    bzoj1798
    java提高篇(三)-----理解java的三大特性之多态
    java提高篇(二)-----理解java的三大特性之继承
    队列的顺序实现(循环数组)与链式实现
    java提高篇(一)-----理解java的三大特性之封装
    设计模式读书笔记-----解释器模式
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6697054.html
Copyright © 2020-2023  润新知