SenseTime Ace Coder Challenge 暨 商汤在线编程挑战赛 D. 白色相簿
从某一点开始,以层次遍历的方式建树
若三点a、b、c互相连接,首先必先经过其中一点a,然后a可以拓展b、c两点,b、c两点的高度是相同的,若b(c)拓展时找到高度与之相同的点,则存在三点互相连接
//等等:该算法正确证有待斟酌,我在看到这个方法的增强版,这方法也许有漏洞
//(注:这想法应该是在17年网络同步赛的时候别人想到的(大致是这样),但貌似写的方法跟我不同)
与acm网络同步赛的某道题有点类似(还有那个定理:若人数大于等于六个,至少存在三个人互相认识,或三个人互不认识)
别人的方法在这(https://www.jisuanke.com/minicourse/1249):
1 /* 2 从某一点开始,以层次遍历的方式建树 3 若三点a、b、c互相连接,首先必先经过其中一点a,然后a可以拓展b、c两点,b、c两点的高度是相同的,若b(c)拓展时找到高度与之相同的点,则存在三点互相连接 4 */ 5 #include <cstdio> 6 #include <cstdlib> 7 #include <cstring> 8 #include <cmath> 9 #include <list> 10 #include <stack> 11 #include <vector> 12 #include <set> 13 #include <map> 14 #include <queue> 15 #include <algorithm> 16 #include <iostream> 17 using namespace std; 18 19 struct node 20 { 21 long d; 22 struct node *next; 23 }*point[100005],*p; 24 long q[100005],dep[100005]; 25 26 int main() 27 { 28 long n,m,i,head,tail,a,b; 29 scanf("%ld%ld",&n,&m); 30 for (i=1;i<=n;i++) 31 point[i]=NULL; 32 for (i=1;i<=m;i++) 33 { 34 scanf("%ld%ld",&a,&b); 35 p=(struct node *) malloc (sizeof(struct node)); 36 p->d=a; 37 p->next=point[b]; 38 point[b]=p; 39 40 p=(struct node *) malloc (sizeof(struct node)); 41 p->d=b; 42 p->next=point[a]; 43 point[a]=p; 44 } 45 for (i=1;i<=n;i++) 46 dep[i]=-1; 47 //有可能有很多块 48 for (i=1;i<=n;i++) 49 if (dep[i]==-1) 50 { 51 q[1]=i; dep[i]=0; 52 head=0; 53 tail=1; 54 while (head<tail) 55 { 56 head++; 57 p=point[q[head]]; 58 while (p) 59 { 60 if (dep[p->d]==-1) 61 { 62 tail++; 63 q[tail]=p->d; 64 dep[p->d]=dep[q[head]]+1; 65 } 66 else if (dep[p->d]==dep[q[head]]) 67 { 68 printf("1"); 69 return 0; 70 } 71 p=p->next; 72 } 73 } 74 } 75 printf("0"); 76 return 0; 77 }