第一次写博客qwq。
首先我们假设所有边都是不定向的,那我们可以把这个问题差分一下,将[l,r]这段+1/-1,那么最后就要使所有区间在[-1,1]之间。
那么可以转化成这样一个模型。我们将一个[l,r]的区间看做一条l---r+1的边,将这些边定向,并且在相邻的奇数度数点之间也连上一条未定向的边(如果走了这条便就说明差值为1),那么就是求一条这个图的欧拉回路。
开始如果有颜色被确定的那就可以被看做被强行定向的。
如何求欧拉回路?我们可以先将所有的不定向边强行定向,这时候按出入度关系,考虑网络流。如果一个点入度in大于初度out,那么从源点向该点连一条流量为(in-out)/2 的边。反之则向汇点连一条流量为(out-in)/2的边,并且将所有不定向的边按开始定的向连起来,流量为1。那么网络流如果经过一条边,实际意义就是将其重定向,那么一个点所需重定向的次数也就是|in-out|/2次。跑出最大流,如果某条原图上的边流量为0,那么就是被重定向了的。判断是否有欧拉回路的方式就是看这个图是否为满流,如此即可。
code
#include<bits/stdc++.h> using namespace std; #define int long long inline void read(int &x) { x=0;int p=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')p=-p;ch=getchar();} while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch-'0'),ch=getchar(); x=x*p; } const int maxn=60005; int m,n; int l[maxn<<1],r[maxn<<1],w[maxn<<1],x[maxn],head[maxn],id[maxn],cnt,cur[maxn],now[maxn<<1],s[maxn<<1],du[maxn],S,T,dis[maxn],top,st[maxn<<1]; struct edge{int to,v,next; }e[maxn<<3]; void add(int x,int y,int z,int h) { e[cnt].to=y; e[cnt].v=z; e[cnt].next=head[x]; head[x]=cnt++; e[cnt].to=x; e[cnt].v=0; e[cnt].next=head[y]; head[y]=cnt++; } int abs(int x) { return x>0?x:-x; } bool bfs() { memset(dis,-1,sizeof(dis)); queue<int>q; dis[S]=0; q.push(S); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=e[i].next) { if(dis[e[i].to]==-1&&e[i].v>0) {dis[e[i].to]=dis[u]+1; q.push(e[i].to);} } } if(dis[T]!=-1)return 1; return 0; } int dfs(int u,int flow) { if(u==T|!flow)return flow; int y=0,mx=0; for(int &i=cur[u];i!=-1;i=e[i].next) { if(dis[e[i].to]==dis[u]+1&&e[i].v&&(y=dfs(e[i].to,min(flow,e[i].v)))) { e[i].v-=y; e[i^1].v+=y; mx+=y; flow-=y; if(!flow)return mx; } } if(!flow)dis[u]=0; return mx; } signed main() { freopen("wait.in","r",stdin); freopen("wait.out","w",stdout); cnt=0; memset(head,-1,sizeof(head)); memset(now,-1,sizeof(now)); read(m);read(n); int tot=0; for(int i=1;i<=m;++i) { read(l[i]);read(r[i]);read(w[i]);r[i]++; s[++tot]=l[i];s[++tot]=r[i]; } sort(s+1,s+tot+1); tot=unique(s+1,s+tot+1)-s-1;top=0; for(int i=1;i<=m;++i) { l[i]=lower_bound(s+1,s+tot+1,l[i])-s; r[i]=lower_bound(s+1,s+tot+1,r[i])-s; if(w[i]==1)du[r[i]]++,du[l[i]]--; else du[l[i]]++,du[r[i]]--; if(w[i]==-1)now[i]=0;st[++top]=l[i];st[++top]=r[i]; } sort(st+1,st+top+1); int nowm=m; for(int i=1;i<=top;i+=2) { if(st[i]==st[i+1])continue;l[++nowm]=st[i];r[nowm]=st[i+1];w[nowm]=-1;now[nowm]=0; du[l[nowm]]++;du[r[nowm]]--; } int sum=0; S=0,T=60002; for(int i=1;i<=tot;++i) { if(du[i]>=0) { add(S,i,(du[i]>>1),-1);sum+=(du[i]>>1); } else { add(i,T,((-du[i])>>1),-1); } } for(int i=1;i<=nowm;++i) { if(w[i]==-1) { id[i]=cnt; add(l[i],r[i],1,i); } } int ans=0; while(bfs()) { memcpy(cur,head,sizeof(head)); ans+=dfs(S,0x3f3f3f); } if(ans!=sum){puts("-1");return 0;} for(int i=1;i<=m;++i) { if(w[i]==-1) { if(e[id[i]].v==0)w[i]=1; else w[i]=0; } } for(int i=1;i<=m;++i) { printf("%d ",w[i]); } }