题解 ladice
将每个物品看成一条无向边,则存在一种合法方案的条件是每个连通块都是一棵树或是基环树
并查集判断即可
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 300010
#define ll long long
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n, l;
int a[N], b[N];
namespace force{
int bel[N];
bool vis[N];
bool dfs(int u, int num) {
vis[u]=1;
if (!bel[u]) {bel[u]=num; vis[u]=0; return 1;}
int now=bel[u], other=a[now]==u?b[now]:a[now];
if (!vis[other] && dfs(other, now)) {bel[u]=num; vis[u]=0; return 1;}
else {vis[u]=0; return 0;}
}
void solve() {
for (int i=1; i<=n; ++i) {
if (!bel[a[i]]) {bel[a[i]]=i; puts("LADICA");}
else if (!bel[b[i]]) {bel[b[i]]=i; puts("LADICA");}
else {
if (dfs(a[i], i)) puts("LADICA");
else if (dfs(b[i], i)) puts("LADICA");
else puts("SMECE");
}
}
exit(0);
}
}
namespace task1{
int dsu[N], siz[N], esiz[N];
inline int find(int p) {return dsu[p]==p?p:dsu[p]=find(dsu[p]);}
inline void uni(int s, int t) {s=find(s); t=find(t); dsu[s]=t; siz[t]+=siz[s]; esiz[t]+=esiz[s];}
void solve() {
for (int i=1; i<=l; ++i) dsu[i]=i, siz[i]=1;
for (int i=1; i<=n; ++i) {
int f1=find(a[i]), f2=find(b[i]);
// cout<<f1<<' '<<f2<<endl;
if (f1==f2) {
if (esiz[f1]<siz[f1]) ++esiz[f1], puts("LADICA");
else puts("SMECE");
}
else {
if (!(esiz[f1]==siz[f1]&&esiz[f2]==siz[f2])) {
uni(f1, f2);
++esiz[find(a[i])];
puts("LADICA");
}
else puts("SMECE");
}
}
exit(0);
}
}
signed main()
{
freopen("ladice.in", "r", stdin);
freopen("ladice.out", "w", stdout);
n=read(); l=read();
for (int i=1; i<=n; ++i) a[i]=read(), b[i]=read();
// force::solve();
task1::solve();
return 0;
}