思路:把每个点拆成(d+1)*n列,行数为可拆分区间数。对所有的有i号点拆分出来的行都要建一条该行到i列的边,那么就能确保有i号点拆出来的行只能选择一行。
#include<set> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<string> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> #define pb push_back #define mp make_pair #define Maxn 1010 #define Maxm 80002 #define LL __int64 #define Abs(x) ((x)>0?(x):(-x)) #define lson(x) (x<<1) #define rson(x) (x<<1|1) #define inf 100000 #define lowbit(x) (x&(-x)) #define clr(x,y) memset(x,y,sizeof(x)) #define Mod 1000000007 using namespace std; int U[Maxn*450],D[Maxn*450],L[Maxn*450],R[Maxn*450],S[Maxn*450],H[Maxn],C[Maxn*450],road[Maxn],id,d,n,m; int g[70][70],row[Maxn*450]; int vi[Maxn]; struct interv{ int s,e,i; int operator <(const interv &temp) const{ if(s==temp.s) return e>temp.e; return s<temp.s; } }p[Maxn],ans[Maxn]; void init(int n) { int i; for(i=0;i<=n;i++){ D[i]=U[i]=i; L[i+1]=i; R[i]=i+1; S[i]=0; } R[n]=0; id=n+1; memset(H,-1,sizeof(H)); } void ins(int r,int c) { int i,j; D[id]=D[c]; U[id]=c; U[D[c]]=id; D[c]=id; if(H[r]<0) H[r]=L[id]=R[id]=id; else{ L[id]=H[r]; R[id]=R[H[r]]; L[R[H[r]]]=id; R[H[r]]=id; } S[c]++; row[id]=r; C[id++]=c; } void Remove(int c) { int i,j; L[R[c]]=L[c]; R[L[c]]=R[c]; for(i=D[c];i!=c;i=D[i]){ for(j=R[i];j!=i;j=R[j]){ D[U[j]]=D[j]; U[D[j]]=U[j]; S[C[j]]--; } } } void Resume(int c) { int i,j; L[R[c]]=c; R[L[c]]=c; for(i=D[c];i!=c;i=D[i]){ for(j=R[i];j!=i;j=R[j]){ D[U[j]]=j; U[D[j]]=j; S[C[j]]++; } } } bool dfs(int step) { int i,j,k,c,temp; if(R[0]==0){ for(i=0;i<step;i++) vi[ans[road[i]].i]=road[i]; for(i=1;i<=n;i++){ if(!vi[i]) printf("0 0\n"); else printf("%d %d\n",ans[vi[i]].s,ans[vi[i]].e); } return true; } temp=inf; for(i=R[0];i;i=R[i]) if(S[i]<temp){ temp=S[i]; c=i; } Remove(c); for(i=D[c];i!=c;i=D[i]){ road[step]=row[i]; for(j=R[i];j!=i;j=R[j]){ Remove(C[j]); } if(dfs(step+1)) return true; for(j=L[i];j!=i;j=L[j]) Resume(C[j]); } Resume(c); return false; } void build() { int i,j,sz,k,r; init(n*(d+1)); int cnt=1; for(i=1;i<=n;i++){ for(j=p[i].s;j<=p[i].e;j++){ for(k=p[i].s;k<=j;k++){ ins(cnt,i); ans[cnt].s=k,ans[cnt].e=j,ans[cnt].i=i; for(r=1;r<=n;r++){ if(!g[i][r]) continue; for(int d=k;d<=j;d++){ ins(cnt,n+(d-1)*n+r); } } cnt++; } } ins(cnt,i); ans[cnt].s=0,ans[cnt].e=0,ans[cnt].i=i; cnt++; } } int main() { int i,j,u,v; while(scanf("%d%d%d",&n,&m,&d)!=EOF){ memset(g,0,sizeof(g)); for(i=1;i<=m;i++){ scanf("%d%d",&u,&v); g[u][v]=g[v][u]=1; } for(i=1;i<=n;i++){ g[i][i]=1; scanf("%d%d",&p[i].s,&p[i].e); p[i].i=i; } build(); if(!dfs(0)) printf("No solution\n"); printf("\n"); } return 0; }