【BZOJ1927】【SDOI2010】星际竞速

【题目链接】

【思路要点】

  • 补档博客,无题解。

【代码】


#include<bits/stdc++.h>

using namespace std;

#define MAXN  5005


#define MAXQ  1000005


#define INF   1e9

template <typename T> void read(T &x) {
  x = 0; int f = 1;
  char c = getchar();
  for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
  for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
  x *= f;
}
struct edge {int dest, flow, cost; unsigned home; };
vector <edge> a[MAXN];
int n, m, s, t, len, flow, cost;
int dist[MAXN], path[MAXN];
unsigned home[MAXN];
void flow_path() {
  int p = t, ans = INF;
  while (p != s) {
      ans = min(ans, a[path[p]][home[p]].flow);
      p = path[p];
  }
  flow += ans, cost += ans * len;
  p = t;
  while (p != s) {
      a[path[p]][home[p]].flow -= ans;
      a[p][a[path[p]][home[p]].home].flow += ans;
      p = path[p];
  }
}
bool spfa() {
  static int q[MAXQ];
  static bool inq[MAXN];
  int l = 0, r = 0;
  q[0] = s, inq[s] = true, dist[s] = 0;
  while (l <= r) {
      int tmp = q[l++];
      inq[tmp] = false;
      for (unsigned i = 0; i < a[tmp].size(); i++)
          if (a[tmp][i].flow != 0 && dist[a[tmp][i].dest] > dist[tmp] + a[tmp][i].cost) {
              dist[a[tmp][i].dest] = dist[tmp] + a[tmp][i].cost;
              path[a[tmp][i].dest] = tmp;
              home[a[tmp][i].dest] = i;
              if (!inq[a[tmp][i].dest]) {
                  inq[a[tmp][i].dest] = true;
                  q[++r] = a[tmp][i].dest;
              }
          }
  }
  len = dist[t];
  for (int i = 0; i <= r; i++)
      dist[q[i]] = INF;
  return len != INF;
}
void addedge(int x, int y, int flow, int cost) {
  a[x].push_back((edge) {y, flow, cost, a[y].size()});
  a[y].push_back((edge) {x, 0, -cost, a[x].size() - 1});
}
int main() {
  read(n), read(m);
  s = 0, t = 2 * n + 1;
  for (int i = 1; i <= n; i++) {
      addedge(s, i, 1, 0);
      addedge(i + n, t, 1, 0);
  }
  for (int i = 1; i <= n; i++) {
      int x; read(x);
      addedge(s, i + n, 1, x);
  }
  for (int i = 1; i <= m; i++) {
      int x, y, z;
      read(x), read(y), read(z);
      if (x > y) swap(x, y);
      addedge(x, y + n, 1, z);
  }
  for (int i = s; i <= t; i++)
      dist[i] = INF;
  while (spfa())
      flow_path();
  printf("%d\n", cost);
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_39972971/article/details/81018751
今日推荐