8.16 模拟赛小结

发布时间 2023-08-16 20:15:04作者: g1ove

前言

最____的一集
题目是从正睿OI捞过来的 找不到原题

T1 文件改名

image
\(n\leq 10^5\)

题意简要:有一堆文件要改名 保证初始的和改正后的名字都没重复
且更改过程中不予许出现重复 求最小操作步数

思考:这题推一下就行
若是状态转移 把这个东西丢到图上
发现可以直接跳过 \(s_i = t_i\) 的情况
然后考虑其它情况
如果是一个图 然后每个点只有一条出边 所以这要么是个链套么是个环 是环答案贡献加一即可
考虑并查集维护

时间复杂度 \(O(n\log n)\)
Code

#include<bits/stdc++.h>
#define N 200005
using namespace std;
int n,cnt,ans;
int fa[N];
string s1,s2;
map <string,int> mp;
int find(int x)
{
	if(fa[x]==x) return x;
	return fa[x]=find(fa[x]);
}
void merges(int u,int v)
{
	u=find(u),v=find(v);
	if(u==v)
	{
		ans++;
		return;
	}
	fa[u]=v;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=2*n;i++)
		fa[i]=i;
	for(int i=1;i<=n;i++)
	{
		cin>>s1>>s2;
		if(s1==s2) continue;
		ans++;
		if(mp[s1]==0) mp[s1]=++cnt;
		if(mp[s2]==0) mp[s2]=++cnt;
		merges(mp[s1],mp[s2]);
	}
	cout<<ans;
	return 0;
}

T2