码迷,mamicode.com
首页 > 其他好文 > 详细

阳阳做任务

时间:2021-03-01 13:47:12      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:printf   暴力   def   pre   起点   clu   要求   一个   +=   

因为 \(u1 < u2, v1 \le v2, u \neq v\),所以没得环,且终点关于起点是不降的,有点 \(DAG\) 的赶脚

无脑暴力:将每个点拆成 \(u1,u2\),分别连源汇,其间的边为限定的值,无源汇上下界最小费用流,注意到有费用的只有 \(t->s\) 的边,费用等于流量

也就是需要求出 \(s->t\) 的最小流,也就是 \(t->s\) 的最大流

然后结合网络流理论,可行流 \(sjb\) 增广一定可以得到最大流

先将 \(s,u1,u2,t\) 直接流满,这是一个可行流

然后留下了 \(t->u2, u1->s\) 的反向边,需要在残量网络上求出 \(t->s\) 的最大流

由于有 \(DAG\) 的感觉,所以退流是不存在的,直接从小到大依次增广即可

换言之,就是依次人工增广

正解的代码量差不多是 \(CF\ Div2\ B\) 的感觉

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 1e6 + 10;

int n, m, a[N], b[N], x[N<<1], y[N<<1], w[N<<1];

LL ans;

int main() {
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &a[i]);
		b[i] = a[i], ans += a[i];
	}
	for (int u, v, i = 1; i <= m; i++) {
		scanf("%d%d", &u, &v);
		scanf("%d", &w[u + v]);
		x[u + v] = u, y[u + v] = v;
	}
	for (int i = 2, j; i <= n + n; i++)
		if (w[i]) {
			j = min(w[i], min(a[x[i]], b[y[i]]));
			a[x[i]] -= j, b[y[i]] -= j, ans -= j;
		}
	printf("%lld\n", ans);
}

阳阳做任务

标签:printf   暴力   def   pre   起点   clu   要求   一个   +=   

原文地址:https://www.cnblogs.com/iqx37f/p/14459062.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!