Loading

NOIP 模拟 $98\; \rm 构造字符串$

题解 \(by\;zj\varphi\)

预处理出来哪些位置是相同的,哪些位置是不同的,相同的用并查集缩点。

按每个集合中最小的元素排序,将相互排斥的集合处理出来。

按顺序填数,每次更新相排斥的集合能填的最小的数。

Code
#include<bits/stdc++.h>
#define ri signed
#define pd(i) ++i
#define bq(i) --i
#define func(x) std::function<x>
namespace IO{
    char buf[1<<21],*p1=buf,*p2=buf;
    #define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++
    #define dg1(x) std::cerr << #x"=" << x << ' '
    #define dg2(x) std::cerr << #x"=" << x << std::endl
    #define Dg(x) assert(x)
    struct nanfeng_stream{
        template<typename T>inline nanfeng_stream &operator>>(T &x) {
            bool f=false;x=0;char ch=gc();
            while(!isdigit(ch)) f|=ch=='-',ch=gc();
            while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=gc();
            return x=f?-x:x,*this;
        }
    }cin;
}
using IO::cin;
namespace nanfeng{
    #define FI FILE *IN
    #define FO FILE *OUT
    template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
    template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
    static const int N=1e3+7;
    int fa[N],mn[N],st[N],bs[N],ct,cnt,n,m,s,t,l;
    struct Bc{int a,b;}bc[N];
    bool vis[N][N],vs[N][N],fg;
    func(int(int)) find=[](int x) {return x==fa[x]?x:fa[x]=find(fa[x]);};
    auto merge=[](int u,int v) {
        u=find(u),v=find(v);
        if (u==v) return;
        fa[v]=u;
        mn[u]=cmin(mn[u],mn[v]);
    };
    inline int main() {
        FI=freopen("str.in","r",stdin);
        FO=freopen("str.out","w",stdout);
        cin >> n >> m;
        for (ri i(1);i<=n;pd(i)) fa[i]=mn[i]=i;
        for (ri i(1);i<=m;pd(i)) {
            cin >> s >> t >> l;
            if (s>t) std::swap(s,t);
            for (ri j(1);j<=l;pd(j)) merge(s+j-1,t+j-1);
            if (t+l<=n) bc[++cnt]={s+l,t+l};
        }
        for (ri i(1);i<=n;pd(i)) if (find(i)==i) st[++ct]=i;
        for (ri i(1);i<=cnt;pd(i)) {
            int a=find(bc[i].a),b=find(bc[i].b);
            if (a==b) return printf("-1\n"),0;
            else vis[a][b]=vis[b][a]=true;
        }
        std::sort(st+1,st+ct+1,[](int x,int y) {return mn[x]<mn[y];});
        for (ri i(1);i<=ct;pd(i)) {
            while(vs[i][bs[st[i]]]) ++bs[st[i]];
            for (ri j(i+1);j<=ct;pd(j))
                if (vis[st[i]][st[j]]) vs[j][bs[st[i]]]=true;
        }
        for (ri i(1);i<=n;pd(i)) printf("%d ",bs[find(i)]);
        printf("\n");
        return 0;
    }
}
int main() {return nanfeng::main();}
posted @ 2021-11-14 20:15  ナンカエデ  阅读(40)  评论(0编辑  收藏  举报