首页 > 其他分享 >AT_arc176_e [ARC176E] Max Vector 题解

AT_arc176_e [ARC176E] Max Vector 题解

时间:2024-09-26 16:36:27浏览次数:9  
标签:num int 题解 tot Vector rest ed ARC176E hd

发现数据范围很小,考虑最小割。先对题面做一个转化:

构造两个序列 \(X=(X_1,X_2,\dots,X_N),Y=(Y_1,Y_2,\dots,Y_N)\) 最小化 \(\sum X_i+Y_i\),有 \(M\) 个限制,每个限制有一个序列 \(A_1,A_2,\dots,A_n\),需要满足 \(\forall i,X_i\ge A_i\) 或者 \(\forall i,Y_i\ge A_i\)。

考虑怎么建图。对每个 \(Y_i\) 新建 \(500\) 个点,每个点从前一个点连一条边权为这个点对应值的边(点 \(1\) 从源点连),表示选这个数。\(500\) 对应的点向汇点连一条边权为 \(+\infty\) 的边。\(X\) 序列同理,但是考虑到后面的限制需要倒着建。

接下来对于每个限制,从每一个 \(X_i\) 的点中 \(A_i\) 对应的点向 \(Y_i\) 的点中 \(A_i+1\) 对应的点连一条边权为 \(+\infty\) 的边,表示如果 \(X_i<A_i\) 那么 \(Y_i\) 就必须 \(\ge A_i\)。

然后跑一边最小割就做完了。

参考代码:

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define rept(i,a,b) for(int i=a;i<b;++i)
#define drep(i,a,b) for(int i=a;i>=b;--i)
using namespace std;
int n,m,s,t,cnt,f[12],f1[12],f2[12],d[10005],a[12][502],b[12][502];
int tot,vr[200000],ed[200000],nx[200000],now[10005],hd[10005];
ll ans;
inline void add(int x,int y,int z){
	vr[++tot]=y,ed[tot]=z,nx[tot]=hd[x],hd[x]=tot;
	vr[++tot]=x,ed[tot]=0,nx[tot]=hd[y],hd[y]=tot;
}
bool bfs(){
	queue<int>q;
	memset(d,0,sizeof(d));
	d[s]=1,now[s]=hd[s],q.push(s);
	while(q.size()){
		int x=q.front();q.pop();
		for(int i=hd[x],y;i;i=nx[i])if(ed[i]&&!d[y=vr[i]]){
			d[y]=d[x]+1,now[y]=hd[y];
			if(y==t)return 1;
			q.push(y);
		}
	}
	return 0;
}
int dinic(int x,int flow){
	if(x==t)return flow;
	int rest=flow,num,i,y;
	for(i=now[x];i;i=nx[i])if(ed[i]&&d[y=vr[i]]==d[x]+1){
		num=dinic(y,min(rest,ed[i]));
		if(num){
			ed[i]-=num,ed[i^1]+=num;
			rest-=num;
			if(!rest)break;
		}else d[y]=0;
	}
	now[x]=i;
	return flow-rest;
}
signed main(){
	scanf("%d%d",&n,&m);
	rep(i,1,n)scanf("%d",&f1[i]);
	rep(i,1,n)scanf("%d",&f2[i]);
	tot=1,t=n*1000+1;
	rep(i,1,n){
		drep(j,500,1){
			a[i][j]=++cnt;
			add(a[i][j+1],cnt,j<f1[i]?1e9:j);
		}
		add(a[i][1],t,1e9);
		rep(j,1,500){
			b[i][j]=++cnt;
			add(b[i][j-1],cnt,j<f2[i]?1e9:j);
		}
		add(b[i][500],t,1e9);
	}
	rep(i,1,m){
		rep(j,1,n)scanf("%d",&f[j]);
		rep(j,1,n){
			rep(k,1,n)add(a[j][f[j]],b[k][f[k]-1],1e9);
		}
	}
	while(bfs())ans+=dinic(s,0x7fffffff);
	printf("%lld",ans);
	return 0;
}

标签:num,int,题解,tot,Vector,rest,ed,ARC176E,hd
From: https://www.cnblogs.com/zifanoi/p/18433664

相关文章

  • 1. 两数之和题解
    题目描述[!NOTE]总结:找出整数数组中两数之后等于目标值的两个数,然后返回其下标给定一个整数数组nums和一个整数目标值target,请你在该数组中找出和为目标值target的那两个整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素......
  • 「FJWC2020Day5-zzq」rng 题解
    题意简述一个长度为\(n\)的实数序列\(a_i\),其中\(a_i\)为\([l_i,r_i]\)中独立均匀随机选取的实数。你只能通过交换相邻两个数,使得\(a_i\)单调不降。你需要求出你最少操作次数的期望,对\(M=998244353\)取模。\(1\leqn\leq10^6\),\(0\leql_i\ltr_i\leq10^{1......
  • 留学期间学业常见问题解决办法,包括不能毕业的状况
    留学期间学业常见问题解决办法,包括不能毕业的状况【国外留学期间,遇到考试挂科的情况,影响了毕业,该怎么办?】考试挂科是一个很常见的现象,而国外院校,因为每个学校的规定不同,有的学校学生有补考机会,但是有的学校如果学生考试挂科情况很严重,或许就没有补考的机会了。这都没关系,重要的是,你......
  • 题解:P10104 [GDKOI2023 提高组] 异或图
    \(\text{Link}\)本题属于集合划分容斥,更多关于集合划分容斥的信息可观看详细揭秘:集合划分容斥的容斥系数。题意给定一个\(n\)个点\(m\)条边的图以及一个长为\(n\)的序列\(a_{1\dotsn}\),有一常数\(C\),你需要求出有多少序列\(b_{1\dotsn}\)满足\(0\leb_i\lea_i\)......
  • 题解:P10198 Infinite Adventure P
    \(\text{Link}\)题意给定\(n\)个数组\(c_{i,0\dotst_i-1}\),其中\(t_i\)为\(2\)的幂。有\(q\)次询问,每次询问给出三个参数\(x,T,\Delta\),接下来会执行\(\Delta\)次\(x\getsc_{x,T\bmodt_x},T\getsT+1\),求出最终的\(x\)。\(n,\sumt\le10^5\),\(q\le5\time......
  • 题解:P10998 Tuple+
    \(\text{Link}\)有意思,记录一下。题意给出\(m\)个互不相同的无序三元组\((u,v,w)\),求有多少无序四元组\((a,b,c,d)\)使得三元组\((a,b,c),(a,b,d),(a,c,d),(b,c,d)\)均存在。\(m\le3\times10^5\)。Bonus:\(m\le2\times10^6\)。题解回忆无向图三元环计数的做法,使......
  • 题解:P10590 磁力块
    \(\text{Link}\)来自传奇讨论区大神@年年有年的\(O(n\logn)\)做法!题意有\(n+1\)块磁铁\(0\simn\),每个磁铁都有四个属性\((d_i,m_i,p_i,r_i)\),如果你拥有了磁铁\(i\),那么你就能吸引并拥有所有满足\(d_j\ler_i,m_j\lep_i\)的磁铁\(j\),初始你只拥有磁铁\(0\),求最......
  • 题解:CF1799F Halve or Subtract
    \(\text{Link}\)介绍一下一种高维wqs的方法。此方法来自@YeahPotato的专栏严谨的WQS二分方法。题意给定一个长为\(n\)的序列\(v_{1\dotsn}\),三个常数\(d,a,b\)。你可以执行若干次以下两种操作:选择\(1\lei\len\),令\(v_i\gets\lceil\frac{v_i}{2}\rceil\)。......
  • C++ VECTOR容器
    SLT中的VECTORvector与string一样是STL标准库中的容器,可以将其理解为C语言中的数组,不过数组里面存放的是内置类型,而为了让其能支持更多的数据类型(自定义类型),C++在STL中规定了vector模板标准,使得我们的自定义类型数据也能存放在数组当中。template<classT,classAlloc=......
  • 勇攀山丘小队(翻越篇)1——题解
    前言胸有丘壑,气吞山河。正片A题:考虑使用DP,由于题目给了2个a不能在一起的限制,所以每次接上一个a都要考虑一下前面的一个状态是否也是a。于是就可以使用\(f,g\)数组,\(f_i\)表示第\(i\)个字母是a的合法情况有多少,\(g_i\)表示第\(i\)个字母是b或c的合法......