正题
题目链接:https://jzoj.net/senior/#main/show/3846
题目大意
长度nnn的直线,mmm条线,将它们分成两边,使同一边不交叉,求是否有方案。
解题思路
将会交叉的直线之间连接边,然后判断是否是二分图即可。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1100;
struct node{int l,r;
}a[N];
struct edge_node{int to,next;
}e[N*N];
int T,n,m,fail,v[N],tot,ls[N];
bool cmp(node x,node y)
{return x.r<y.r;}
void addl(int x,int y)
{e[++tot].to=y;e[tot].next=ls[x];ls[x]=tot;
}
void dfs(int x,int w)
{v[x]=w;for(int i=ls[x];i;i=e[i].next){int y=e[i].to;if(fail) break;if(v[y]&&v[y]!=(w^1)) {fail=1;break;}if(v[y]) continue;dfs(y,w^1);}
}
int main()
{scanf("%d",&T);while(T--){scanf("%d%d",&n,&m);for(int i=1;i<=m;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+m,cmp);fail=tot=0;memset(v,0,sizeof(v));memset(ls,0,sizeof(ls));for(int i=1;i<=m;i++)for(int j=i+1;j<=m;j++)if(a[i].l<a[j].l&&a[j].l<a[i].r&&a[i].r<a[j].r)addl(i,j),addl(j,i);for(int i=1;i<=m;i++)if(!v[i])dfs(i,2);if(fail) printf("non\n");else printf("sane\n");}
}