七天使的通讯
Posted cutemush
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了七天使的通讯相关的知识,希望对你有一定的参考价值。
n个天使排成一条直线,某些天使之间需要互相联系,他们之间的通讯可以通过黑白两种通道中的一种;所有通道
必须在直线同侧(另一侧是地面);为了保证通讯效率,同种颜色的所有通道之间不能相交。请计算能否建立这种
通讯方案。
Input
第一行一个数T,表示接下来有T个询问。
对于每个询问:第一行两个数n,m,分别表示有n个天使、需要建立通讯线路的天使有m对;
接下来有m行,每行两个数a、b,表示a、b两个天使需要通讯。
1<=n<=5000,1<=m<=1000,1<=T<=10,1<=a<=n,1<=b<=n
数据保证每对(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
【提示】
当两条线路有一对相同的端点时,这两条线路不相交。
也就是说,对于线路(a,b)和线路(c,d)(a<b且c<d),当且仅当a<c<b<d或者c<a<d<b时这两条线路相交。?
Sol:
将每个通道设为一个节点,先暴力判断每两条通道如果是同种颜色会不会相交,如果会相交就在这两个节点之间连无向边,说明它们不能为同种颜色(必须在二分图两边)。然后对组成的无向图进行二分图判定(DFS染色),如果染色成功说明该图是一个二分图,即有解,否则无解。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=1005,maxk=1000005; int n,m,ca,color[maxn],tot,now[maxn],prep[maxk],son[maxk],wi[maxn][2]; bool bo; void add(int x,int y) { tot++,prep[tot]=now[x],now[x]=tot,son[tot]=y; } void dfs(int x,int y) { color[x]=y; for (int i=now[x],so=son[i];i;i=prep[i],so=son[i]) { if (color[so]==-1) { dfs(so,1-y); } else if (color[x]==color[so]) bo=0; } } int main(){ scanf("%d",&ca); while (ca--) { scanf("%d%d",&n,&m); bo=1; tot=0,memset(now,0,sizeof(now)); for (int i=1;i<=m;i++) { scanf("%d%d",&wi[i][0],&wi[i][1]); if (wi[i][0]>wi[i][1]) swap(wi[i][0],wi[i][1]); } int a,b,c,d; for (int i=1;i<=m;i++) { for (int j=1;j<=m;j++) { a=wi[i][0],b=wi[i][1],c=wi[j][0],d=wi[j][1]; if (a<c&&c<b&&b<d) add(i,j),add(j,i); } } memset(color,-1,sizeof(color)); for (int i=1;i<=m;i++) if (color[i]==-1) dfs(i,1); if (bo==1) puts("sane"); else puts("non"); } return 0; }
以上是关于七天使的通讯的主要内容,如果未能解决你的问题,请参考以下文章