[ABC317G] Rearranging

Problem Statement

There is a grid with N rows and M columns. The square at the i-th row from the top and the j-th column from the left contains the integer Ai,j.
Here, the squares contain M occurrences of each of 1,,N, for a total of NM integers.

You perform the following operations to swap the numbers written on the squares.

  • For i=1,,N in this order, do the following.
    • Freely rearrange the numbers written in the i-th row. That is, freely choose a permutation P=(P1,,PM) of 1,,M, and replace Ai,1,,Ai,M with Ai,P1,,Ai,PM simultaneously.

Your goal is to perform the operations so that each column contains each of 1,,N once. Determine if this is possible, and if so, print such a resulting grid.

盲猜没有无解。

一列一列处理,每次算出一列。而某一列可以建出二分图计算。如果第 i 行存在数 j 就从左部 i 向右部 j 连一条边,问题变为找一个匹配,匈牙利即可(为什么大家都Dinic 的)

现在要证明不存在无解情况,也就是不存在某一时刻二分图不存在完美匹配,转成Hall 定理的话,某 k 行出现过的不同的数一定超过 k,设剩下 m 列没处理,那么每种数最多出现 m 次, k 行中共有 km 个数,所以至少会有 k 个不同的数,二分图一定存在完美匹配。

#include<bits/stdc++.h>
using namespace std;
const int N=4e5+5;
int n,m,a,b,c,vs[N],st[N],tp,idx,dfn[N],low[N];
struct graph{
	int hd[N],e_num;
	struct edge{
		int v,nxt;
	}e[N<<1];
	void add_edge(int u,int v)
	{
		e[++e_num]=(edge){v,hd[u]};
		hd[u]=e_num; 
		e[++e_num]=(edge){u,hd[v]};
		hd[v]=e_num; 
	}
}g,h;
int read()
{
	int s=0;
	char ch=getchar();
	while(ch<'0'||ch>'9')
		ch=getchar();
	while(ch>='0'&&ch<='9')
		s=s*10+ch-48,ch=getchar();
	return s;
}
void tarjan(int x)
{
	dfn[x]=low[x]=++idx;
	st[++tp]=x;
	for(int i=g.hd[x];i;i=g.e[i].nxt)
	{
		int v=g.e[i].v;
		if(!dfn[v])
		{
			tarjan(v);
			low[x]=min(low[x],low[v]);
			if(low[v]==dfn[x])
			{
				++n;
				while(st[tp]^v)
					h.add_edge(n,st[tp--]);
				h.add_edge(n,st[tp--]);
				h.add_edge(x,n);
			}
		}
		else
			low[x]=min(low[x],dfn[v]);
	}
}
void dfs(int x,int y)
{
	st[++tp]=x;
	if(x==c)
	{
		for(int i=1;i<=tp;i++)
			vs[st[i]]=1;
		return;
	}
	for(int i=h.hd[x];i;i=h.e[i].nxt)
		if(h.e[i].v^y)
			dfs(h.e[i].v,x);
	--tp;
}
int main()
{
	n=read(),m=read(),a=read(),b=read(),c=read();
	for(int i=1,u,v;i<=m;i++)
		g.add_edge(read(),read());
	tarjan(a);
	dfs(a,0);
	for(int i=h.hd[b];i;i=h.e[i].nxt)
		if(vs[h.e[i].v])
			return puts("Yes"),0;
	puts("No");
}
posted @   灰鲭鲨  阅读(41)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2022-09-04 [ABC261A] Intersection
2022-09-04 [ABC261B] Tournament Result
2022-09-04 [ABC261C] NewFolder(1)
2022-09-04 [ABC261F] Sorting Color Balls
2022-09-04 [ABC261D] Flipping and Bonus
2022-09-04 [ABC261E] Many Operations
2022-09-04 [ABC261Ex] Game on Graph
点击右上角即可分享
微信分享提示