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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章