首页 > 其他分享 >CF1666K Kingdom Partition 题解

CF1666K Kingdom Partition 题解

时间:2023-02-05 11:12:47浏览次数:85  
标签:Kingdom 连通 ch SS 题解 TT Partition TS ST

神仙网络流题。

Description

传送门

Solution

考虑最小割,将每个点 \(u\) 拆成 \(L_u,R_u\) 两个点。对于每一条原图中的边 \((u,v,w)\),连双向边 \((L_u,R_v,w),(L_v,R_u,w)\),边权为 \(w\)。加入源汇后跑最小割,将所有点 \(u\) 划分为四类:

  • SS: \(L_u,R_u\) 均与源点 \(S\) 连通。

  • TT: \(L_u,R_u\) 均与汇点 \(T\) 连通。

  • ST: \(L_u,R_u\) 分别与 \(S,T\) 连通。

  • TS: \(L_u,R_u\) 分别与 \(T,S\) 连通。

考虑一条原图中的边 \((u,v,w)\),讨论 \(u,v\) 分别属于哪一类点,有 \(16\) 情况:

SS TT ST TS
SS 0 2 1 1
TT 2 0 1 1
ST 1 1 2 0
TS 1 1 0 2

\(0,1,2\) 分别表示产生的代价。

给出结论:在原图上,SS 与 TT 类点不会直接相连。这是因为,对于 SS 与 TT 类点的导出子图的每个连通块,若其中同时存在 SS,TT,则将该连通块全部换成 SS 严格更优。

从而,我们可以列出一张新的表格:

SS / TT ST TS
SS / TT 0 1 1
ST 1 2 0
TS 1 0 2

将 ST,TS,SS/TT 分别对应 Adrian, Beatrice and Cecilia 即可。

时间复杂度 \(O(\text{Dinic}(m,n))\)。实现有一定细节:

  • \(S\) 连向 \(L_x\),\(R_x\) 连向 \(T\) 以保证 \(x\) 属于 Adrian,边权均为 \(\inf\)。
  • \(S\) 连向 \(R_y\),\(L_y\) 连向 \(T\) 以保证 \(y\) 属于 Beatrice,边权均为 \(\inf\)。
  • 对于每条原图中的边 \((u,v,w)\),需要连双向边 \((L_u,R_v,w),(L_v,R_u,w)\)。加上反悔用的反边,相当于多建了 \(8\) 条边。别人建的边比我少,好像只用 \(4\) 条,我自带大常数。
  • 根据最后一轮 bfs 每个节点是否被访问过,可以确定其属性。
  • 点数,边数虽然都是 \(O(n)\),但常数较大,数组不要开小了。

Solution

#include <bits/stdc++.h>
#define int long long
#define inf 1000000000000000007
using namespace std;
const int N=2005;

int read(){
	int s=0,w=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-')  w=-w;ch=getchar();}
	while (ch>='0'&&ch<='9'){s=(s<<1)+(s<<3)+(ch^'0');ch=getchar();}
	return s*w;
}
int n,m,x,y,S,T,st,ed,ans,cnt=1;
int L[N],R[N],head[N],cur[N],dep[N],que[N];
struct edge{int nxt,to,f;}e[N<<4];

void add_edge(int u,int v,int f){e[++cnt]=edge{head[u],v,f},head[u]=cnt;}
void Add(int u,int v,int f){add_edge(u,v,f),add_edge(v,u,0);}
void Add_bir(int u,int v,int f){Add(u,v,f),Add(v,u,f);}
bool bfs(){
	for (int i=S;i<=T;i++)  cur[i]=head[i],dep[i]=0;
	que[st=ed=1]=S,dep[S]=1;
	while (st<=ed){
		int u=que[st++];
		for (int i=head[u];i;i=e[i].nxt){
			int v=e[i].to;
			if (!dep[v]&&e[i].f)  dep[v]=dep[u]+1,que[++ed]=v;
		}
	}
	return dep[T];
}
int dfs(int u,int Flow){
	if (u==T)  return Flow;

	int Out=0;
	for (int i=cur[u];i;i=e[i].nxt){
		if (!Flow)  break;
		cur[u]=i;

		int v=e[i].to;
		if (e[i].f&&dep[v]==dep[u]+1){
			int tmp=dfs(v,min(Flow,e[i].f));
			e[i].f-=tmp,e[i^1].f+=tmp,Flow-=tmp,Out+=tmp;
		}
	}
	return Out;
}
void printans(){
	printf("%lld\n",ans);
	for (int i=1;i<=n;i++){
		int x=dep[L[i]],y=dep[R[i]];
		if (x==y)  putchar('C');
		else if (x)  putchar('A');
		else putchar('B');
	}
}
signed main(){
	n=read(),m=read(),x=read(),y=read();
	for (int i=1;i<=n;i++)  L[i]=(++T),R[i]=(++T);
	T++;
	while (m--){
		int u=read(),v=read(),w=read();
		Add_bir(L[u],R[v],w),Add_bir(L[v],R[u],w);
	}
	Add_bir(S,L[x],inf),Add_bir(R[x],T,inf);
	Add_bir(S,R[y],inf),Add_bir(L[y],T,inf);
	while (bfs())  ans+=dfs(S,inf);
	return printans(),0;
}

标签:Kingdom,连通,ch,SS,题解,TT,Partition,TS,ST
From: https://www.cnblogs.com/ducati/p/17093045.html

相关文章

  • 题解 ARC155D Avoid Coprime Game
    题解ARC155DAvoidCoprimeGame题意给定一个可重集\(S\),保证\(\gcd_{x\inS}(x)=1\),维护一个初始为\(0\)的整数\(G\),双方轮流操作,每次每人选择\(S\)中一个数......
  • circle 题解(思维+堆)
    题目有\(n\)个圆心在\(x\)轴上的不相交的圆(存在边界重合),求这些圆将平面分为几部分。保证\(1\leqn\leq3\times10^5\),\(-10^9\leqx_i,y_i\leq10^9\)。一个......
  • CF765F Souvenirs 题解
    Preface在会压位Trie的前提下,本题最好想的做法应该是压位Trie+回滚莫队,可是竟然没人写这个做法的题解?Solution我们先转化题意:设\(a_i\)在\([l,r]\)中的前驱后继......
  • PAT乙级题解
    1001害死人不偿命的(3n+1)猜想传送门知识点:简单模拟思路:判断奇偶,根据题意即可参考代码:点击查看代码#include<iostream>usingnamespacestd;intmain(){i......
  • 题解 G. Grammar Path 2020-2021 ICPC NERC (NEERC), North-Western Russia Regional
    传送门【大意】给定一个CNF和一个有向图。有向图上的每一条边都写上了一个字母。要求你从\(s\)到\(t\)走一条尽可能短的路,且将经过的字母写下来后,这个字符串能被......
  • [JOI 2021 Final] 地牢 3 题解
    做法学习自日语酱的题解/hs/bx。本文旨在讲述我个人看完题解对此题做法的理解,可以视作对日语酱题解的注解(?。本人很菜,很可能出错,请谅解qwq。首先,对样例进行模拟,得到......
  • 最小公倍佩尔数 题解
    首先需要知道\(f\)是个啥这里直接给出结论,过程可以看大佬的博客\(f(n)=2f(n-1)+f(n-2)\)\(f(0)=0\)\(f(1)=1\)这种类似斐波那契数列的递推式有结论\(gcd(......
  • P3119 [USACO15JAN]Grass Cownoisseur G 题解
    做过的原题,模拟赛时PDF里的题面实在有点难受。首先有显然结论:在一个环上反走一定是不值的,因为环上的点本来就相互可达。所以考虑缩点。缩点后的问题可以看成:求对于每一......
  • P8368 [LNOI2022] 串 题解
    题目链接题目分析题目要求我们构造一个最长的\(T\)序列,我们首先从每个\(T_i\)入手,思考如何安排才能合法。容易观察到对于每个\(T_i\),合法的\(T_{i-1}\)有两种方......
  • 【题解】P5219 无聊的水题 I
    思路prufer序列+卷积优化dp.首先考虑到令\(a\)为原树的prufer序列,则\(\sum\limits_{i=1}^{n-2}[a_i=k]=\operatorname{deg}(k)\),其中\(\operatorname......