[SDOI 2009] 晨跑
Posted evenbao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[SDOI 2009] 晨跑相关的知识,希望对你有一定的参考价值。
[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=1877
[算法]
不难看出,第一问要求的是最大流,第二问求的是最小费用最大流
注意建图时要将每个点拆成入点和出点,防止经过同一个地点多次
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 1010 #define MAXM 40010 const int inf = 2e9; struct edge { int to,w,cost,nxt; } e[MAXM << 1]; int i,n,m,tot,a,b,c,S,T,ans1,ans2; int pre[MAXN << 1],dist[MAXN << 1],incf[MAXN << 1],head[MAXN << 1]; template <typename T> inline void read(T &x) { int f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) { if (c == ‘-‘) f = -f; } for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘; x *= f; } inline void addedge(int u,int v,int w,int cost) { tot++; e[tot] = (edge){v,w,cost,head[u]}; head[u] = tot; tot++; e[tot] = (edge){u,0,-cost,head[v]}; head[v] = tot; } inline bool spfa() { int i,l,r,u,v,w,cost; static int q[MAXN << 1]; static bool inq[MAXN << 1]; for (i = 1; i <= 2 * n; i++) { dist[i] = inf; incf[i] = inf; inq[i] = false; } q[l = r = 1] = S; inq[S] = true; pre[S] = 0; dist[S] = 0; while (l <= r) { u = q[l]; l++; inq[u] = false; for (i = head[u]; i; i = e[i].nxt) { v = e[i].to; w = e[i].w; cost = e[i].cost; if (w && dist[u] + cost < dist[v]) { dist[v] = dist[u] + cost; incf[v] = min(incf[u],w); pre[v] = i; if (!inq[v]) { inq[v] = true; q[++r] = v; } } } } if (dist[T] != inf) return true; else return false; } inline void update() { int pos,x = T; while (x != S) { pos = pre[x]; e[pos].w -= incf[T]; e[pos ^ 1].w += incf[T]; x = e[pos ^ 1].to; } ans1 += incf[T]; ans2 += dist[T] * incf[T]; } int main() { read(n); read(m); tot = 1; addedge(1,n + 1,inf,0); addedge(n,2 * n,inf,0); for (i = 2; i < n; i++) addedge(i,i + n,1,0); for (i = 1; i <= m; i++) { read(a); read(b); read(c); addedge(a + n,b,1,c); } S = 1; T = 2 * n; while (spfa()) update(); printf("%d %d ",ans1,ans2); return 0; }
以上是关于[SDOI 2009] 晨跑的主要内容,如果未能解决你的问题,请参考以下文章