【JZOJ3846】七天使的通讯【dfs】
题目大意:
题目链接:https://jzoj.net/senior/#main/show/3846
n个天使排成一条直线,某些天使之间需要互相联系,他们之间的通讯可以通过黑白两种通道中的一种;所有通道必须在直线同侧(另一侧是地面);为了保证通讯效率,同种颜色的所有通道之间不能相交。请计算能否建立这种通讯方案。
思路:
将每一条通道看做一个点,如果两条通道相交,那么就将这个两个点连边。
然后进行黑白染色即可。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1010;
int T,n,m,tot,head[N],col[N];
bool flag;
struct edge
{
int next,to;
}e[N*N*2];
struct node
{
int l,r;
}a[N];
bool cmp(node x,node y)
{
return x.l<y.l;
}
void add(int from,int to)
{
e[++tot].to=to;
e[tot].next=head[from];
head[from]=tot;
}
void dfs(int x,int fa)
{
for (int i=head[x];~i;i=e[i].next)
{
int v=e[i].to;
if (v!=fa)
{
if (col[x]==col[v])
{
flag=0;
return;
}
else if (!col[v])
{
col[v]=3-col[x];
dfs(v,x);
}
}
if (!flag) return;
}
}
int main()
{
scanf("%d",&T);
while (T--)
{
tot=0;
memset(head,-1,sizeof(head));
memset(col,0,sizeof(col));
scanf("%d%d",&m,&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
if (a[i].l>a[i].r) swap(a[i].l,a[i].r);
}
sort(a+1,a+1+n,cmp);
for (int i=1;i<=n;i++)
for (int j=i+1;j<=n;j++)
if (a[i].l!=a[j].l && a[i].r>a[j].l && a[i].r<a[j].r) add(i,j),add(j,i);
flag=1;
for (int i=1;i<=n;i++)
if (!col[i])
{
col[i]=1;
dfs(i,0);
if (!flag) break;
}
if (flag) printf("sane\n");
else printf("non\n");
}
return 0;
}