BZOJ P4883 [Lydsy2017年5月月赛]棋盘上的守卫 做题记录

前置芝士:kruskal 求最小生成树,并查集

原题链接:hydro

思路

我们将它建模成图论问题,相当于从 \(i\)\(j\) 连一条长度为 \(a_{i,j}\) 的边,然后使得每个点都有一个入度,那么就是在求最小基环树森林。

至于基环树森林怎么求呢?我们使用像 kruskal 的思想,按照边的长度的大小对边进行排序,每一次加入一条边对他们进行讨论:

  • 如果他们不在一棵树上,而且两个点所在的连通块不是两个都有环,那么他们可以合并。
  • 如果他们在一棵树上,而且他们所在的数上没有环,他们可以连边。

时间复杂度:\(O(nm \log(nm))\)
难点/坑点: 无。

点击查看代码
#include<bits/stdc++.h>

#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 200050

int n,m;
struct node {
	int u,v,val;
	bool operator<(const node &x) const { return val<x.val; }
}edge[maxn];
int top;

int fa[maxn],cr[maxn];
int find(int x) {return fa[x]==x?x:fa[x]=find(fa[x]); }

void work() {
	in2(n,m);
	For(i,1,n) {
		For(j,1,m) {
			int x=read();
			edge[++top]={i,j+n,x};
		}
	}
	For(i,1,n+m) fa[i]=i;
	sort(edge+1,edge+top+1);
	ll ans=0;
	For(i,1,top) {
		auto [u,v,d]=edge[i];
		if(find(u)!=find(v)&&!(cr[fa[u]]&&cr[fa[v]])) {
			cr[fa[u]]|=cr[fa[v]];
			fa[fa[v]]=fa[u];
			ans+=d;
		} else if(!cr[fa[u]]) {
			cr[fa[u]]=1;
			ans+=d;
		}
	}
	cout<<ans;
}

signed main() {
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	int _=1;
//	_=read();
	For(i,1,_) {
		work();
	}
	return 0;
}
posted @ 2024-12-25 19:49  coding_goat_qwq  阅读(18)  评论(0)    收藏  举报