题解 构造字符串
这题我居然不会……
每个限制条件实际上等价于 \(z-1\) 个形如 \(a_i=a_j\) 的条件和一个 \(a_i\neq a_j\) 的条件
发现支持复杂度 \(O(n^2)\),于是暴力并查集,贪心填数即可
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1010
#define ll long long
#define fir first
#define sec second
#define make make_pair
#define pb push_back
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
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, m;
int dsu[N], ans[N], val[N], tot;
bool vis[N];
pair<int, int> diff[N];
vector<int> ags[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); if (s!=t) dsu[s]=t;}
signed main()
{
freopen("str.in", "r", stdin);
freopen("str.out", "w", stdout);
n=read(); m=read();
memset(val, -1, sizeof(val));
for (int i=1; i<=n; ++i) dsu[i]=i;
for (int i=1,x,y,z; i<=m; ++i) {
x=read(); y=read(); z=read();
if (z==0) diff[++tot]=make(x, y);
else {
for (int k=0; k<z; ++k) uni(x+k, y+k);
if (x+z<=n && y+z<=n) {
diff[++tot]=make(x+z, y+z);
}
}
}
for (int i=1; i<=tot; ++i) ags[find(diff[i].fir)].pb(find(diff[i].sec)), ags[find(diff[i].sec)].pb(find(diff[i].fir));
// for (int i=1; i<=tot; ++i) cout<<"diff: "<<diff[i].fir<<' '<<diff[i].sec<<endl;
// cout<<"bel: "; for (int i=1; i<=n; ++i) cout<<find(i)<<' '; cout<<endl;
for (int i=1; i<=tot; ++i) if (find(diff[i].fir)==find(diff[i].sec)) {puts("-1"); return 0;}
for (int i=1; i<=n; ++i) {
if (val[find(i)]!=-1) ans[i]=val[find(i)];
else {
memset(vis, 0, sizeof(vis));
for (auto it:ags[find(i)]) if (~val[it]) vis[val[it]]=1;
for (int j=0; ; ++j) if (!vis[j]) {val[find(i)]=j; break;}
ans[i]=val[find(i)];
}
}
for (int i=1; i<=n; ++i) printf("%d%c", ans[i], " \n"[i==n]);
return 0;
}