jzoj 3846. 七天使的通讯(angelus) (Standard IO)

Description
n个天使排成一条直线,某些天使之间需要互相联系,他们之间的通讯可以通过黑白两种通道中的一种;所有通道必须在直线同侧(另一侧是地面);为了保证通讯效率,同种颜色的所有通道之间不能相交。请计算能否建立这种通讯方案。

Input
第一行一个数T,表示接下来有T个询问。
对于每个询问:第一行两个数n,m,分别表示有n个天使、需要建立通讯线路的天使有m对;接下来有m行,每行两个数a、b,表示a、b两个天使需要通讯。

Output
对于每个询问,输出一行“sane”表示有可行方案、“non”表示无解。

Sample Input
1
7 5
1 3
2 7
3 4
7 4
6 5

Sample Output
sane

Data Constraint
对于 20%的数据,1<=n<=50,1<=m<=15
对于 50%的数据,1<=n<=1000,1<=m<=300
对于 100%的数据,1<=n<=5000,1<=m<=1000,1<=T<=10,1<=a<=n,1<=b<=n
数据保证每对(a,b)不重复,且a不等于b

Hint
【提示】
当两条线路有一对相同的端点时,这两条线路不相交。
也就是说,对于线路(a,b)和线路(c,d)(a<b且c<d),当且仅当a<c<b<d或者c<a<d<b时这两条线路相交。
在这里插入图片描述
//written by zzy

题目大意:

给你NN个天使,MM个通道,求是否有种方案给所有通道黑白染色,使通道两两不相交(通道必须在同一侧)。

题解:

不难发现,如果没有可行方案,必有至少33条边(l,r)(l,r)满足li<lj<lk<ri<rj<rkli<lj<lk<ri<rj<rk
那我们只需枚举每个通道的ll,往后至rr的范围内寻找至少两个递增的l,rl,r
若能找到,则说明没有可行方案。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define M 1005
using namespace std;

int i,j,k,n,a,b,t,l,p,q,num;
bool _can;

struct E {
	int l,r;
}e[M];

bool cmp(E a,E b) {
	return (a.l<b.l)||(a.l==b.l&&a.r<=b.r);
}

int main()
{
	scanf("%d",&t);
	for (l=1;l<=t;l++) {
    
	scanf("%d%d",&a,&n);
	for (i=1;i<=n;i++) {
		scanf("%d%d",&a,&b);
		e[i].l=min(a,b),e[i].r=max(a,b);
	}
	sort(e+1,e+1+n,cmp);
	_can=true;
	for (i=1;i<=n;i++)
	{
		num=0;
		p=e[i].l; q=e[i].r;
		for (j=i+1;j<=n;j++) {
		 if (e[j].l>=e[i].r) break;
		 if (e[j].l>p&&e[j].r>q) 
		  num++,p=e[j].l,q=e[j].r;
	    }
	    if (num>=2) {
	    	_can=false; break;
	    }
	}
	 if (_can) printf("sane\n");
	 else printf("non\n");
	  for (i=1;i<=n;i++) e[i].l=0,e[i].r=0;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章