题意问你 给你 n个人 每个人 有两种属性 可以选择 A 选择 B 但是有些人 不能同时选 A或者 同时选B 问最后得到的 MAX - MIN 最小
首先没有 人限制的话 那么就是个经典题 滑动窗口求 差值最小 只需要把两个值拆分 sort一下 然后每次找到 n 个人 的属性取一下 min 即可
有限制的话 无非是 把人变成了联通块 多个联通块 组合求差值 此题 是 每个人选择两种值 每个联通块就有两种 maxn 和 minn 我们只需要拆分成 4种值进行排序即可
#include<iostream>
#include<algorithm>
#include<cstring>
#define x first
#define y second
using namespace std;
const int N = 2e5 + 10,M = N * 2;
typedef pair<pair<int,int> ,pair<int,int> > PII;
struct node{
int x,id,type;
bool operator < (const node &p)const{
return x < p.x;
}
}c[M * 2];
int a[N],b[N];
int head[N],to[M],last[M],cnt;
void add(int a,int b){
to[++cnt] = b;
last[cnt] = head[a];
head[a] = cnt;
}
bool flag;
int color[N];
PII get_color(int x,int pre){
int maxn1 = a[x],minn1 = a[x];
int maxn2 = b[x],minn2 = b[x];
for(int i = head[x]; i != -1; i = last[i]){
int j = to[i];
if(pre == j) continue;
if(color[j] == 3) color[j] = color[x] ^ 1;
else{
if(color[j] != (color[x] ^ 1)){
flag = false;
return {
{
0,0},{
0,0}};
}else continue;
}
PII p = get_color(j,x);
maxn1 = max(maxn1,p.y.x);
minn1 = min(minn1,p.y.y);
maxn2 = max(maxn2,p.x.x);
minn2 = min(minn2,p.x.y);
}
return {
{
maxn1,minn1},{
maxn2,minn2}};
}
PII ve[N];
int st[N][3];
int main(){
int t;
cin >> t;
int CASE = 0;
while(t--){
int n,m;
cin >> n >> m;
memset(st,0,sizeof st);
memset(head,-1,sizeof head);
flag = true;
cnt = 0;
for(int i = 1; i <= m; i++){
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
for(int i = 1; i <= n; i++){
scanf("%d%d",&a[i],&b[i]);
}
for(int i = 1; i <= n; i++) color[i] = 3;
int ans = 0;
for(int i = 1; i <= n; i++){
if(color[i] == 3){
color[i] = 1;
ve[++ans] = get_color(i,0);
}else continue;
}
printf("Case %d: ",++CASE);
if(!flag){
printf("IMPOSSIBLE\n");
continue;
}
int d = 0;
for(int i = 1; i <= ans; i++){
c[++d] = {
ve[i].x.x,i,0};
//cout << ve[i].x.x << " " << ve[i].x.y << " " << ve[i].y.x<< " " << ve[i].y.y << "asd" <<endl;
c[++d] = {
ve[i].x.y,i,0};
c[++d] = {
ve[i].y.x,i,1};
c[++d] = {
ve[i].y.y,i,1};
}
sort(c + 1,c + d + 1);
int minn = 0x3f3f3f3f;
int r = 1,s = 0;
for(int i = 1; i <= d; i++){
st[c[i - 1].id][c[i - 1].type]--;
if(st[c[i - 1].id][c[i - 1].type] == 1 && st[c[i - 1].id][c[i - 1].type ^ 1] != 2) s--;
while(r <= d && s < ans){
st[c[r].id][c[r].type]++;
if(st[c[r].id][c[r].type] == 2 && st[c[r].id][c[r].type ^ 1] != 2) s++;
r++;
}
if(c[i].id == c[r - 1].id && c[i].type != c[r - 1].type) continue;
if(s != ans) continue;
minn = min(minn,c[r - 1].x - c[i].x);
}
cout << minn << endl;
}
return 0;
}