UVa 1349 Optimal Bus Route Design (最佳完美匹配)

Posted dwtfukgv

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVa 1349 Optimal Bus Route Design (最佳完美匹配)相关的知识,希望对你有一定的参考价值。

题意:给定一个有向图,让你找出若干个图,使得每个点恰好属于一个圈,并且总的权和最小。

析:每个点都有唯一的一个圈,也就是说每一点都有唯一的后继,那么我们就可以转换成求一个图的最小权的最佳完全匹配,可以用最小费用流来求,

先把每个结点拆成两个点,假设是x,y,然后建立一个源点,向每个点的x连一条容量为1的边,建立一个汇点,每个点的y向汇点连一条容量为1的边,

每条边u,v,也连接一条容量为1,费用为权值的边,最小求一个最小费用流即可。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std;

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-5;
const int maxn = 2000 + 10;
const int mod = 1e6;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c){
  return r >= 0 && r < n && c >= 0 && c < m;
}
struct Edge{
  int from, to, cap, flow;
  LL cost;
};

struct MCMF{
  int n, m;
  vector<Edge> edges;
  vector<int> G[maxn];
  int inq[maxn];
  LL d[maxn];
  int p[maxn];
  int a[maxn];

  void init(int n){
    this->n = n;
    for(int i = 0; i < n; ++i)  G[i].clear();
    edges.clear();
  }

  void addEdge(int from, int to, int cap, LL 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 s, int t, int &flow, LL &cost){
    for(int i = 0; i < n; ++i)  d[i] = INF;
    memset(inq, 0, sizeof inq);
    d[s] = 0;  inq[s] = 1;  p[s] = 0;   a[s] = INF;

    queue<int> q;
    q.push(s);
    while(!q.empty()){
      int u = q.front();  q.pop();
      inq[u] = 0;
      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;
          p[e.to] = G[u][i];
          a[e.to] = min(a[u], e.cap-e.flow);
          if(!inq[e.to])  q.push(e.to),  inq[e.to] = 1;
        }
      }
    }
    if(d[t] == INF)  return false;
    flow += a[t];
    cost += d[t] * a[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 minCost(int s, int t, LL &cost){
    int flow = 0;  cost = 0;
    while(BellmanFord(s, t, flow, cost));
    return flow;
  }
};
MCMF mcmf;

int main(){
  while(scanf("%d", &n) == 1 && n){
    mcmf.init(n+n+2);
    int v;  LL val;
    int s = 0, t = n+n+1;
    for(int i = 1; i <= n; ++i){
     // mcmf.addEdge(i, i+n, 1, 0);
      mcmf.addEdge(s, i, 1, 0);
      mcmf.addEdge(i+n, t, 1, 0);
      while(scanf("%d", &v) == 1 && v){
        scanf("%lld", &val);
        mcmf.addEdge(i, v+n, 1, val);
      }
    }

    LL ans;
    if(mcmf.minCost(s, t, ans) == n)  printf("%lld\n", ans);
    else  printf("N\n");
  }
  return 0;
}

 

以上是关于UVa 1349 Optimal Bus Route Design (最佳完美匹配)的主要内容,如果未能解决你的问题,请参考以下文章

题解 UVA1349 Optimal Bus Route Design

UVa 1349 Optimal Bus Route Design (最佳完美匹配)

uvalive 3353 Optimal Bus Route Design

UVaLive 3353 Optimal Bus Route Design (最小费用流)

UVA 10304 Optimal Binary Search Tree

UVA10304 Optimal Binary Search Tree最优排序二叉树