【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
");
			else printf("non
");
	}
	return 0;
}
原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998000.html