六度分离(floyd算法+dijskra+SPFA)
六度分离
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 5411 Accepted Submission(s): 2195
Problem Description
1967年,美国著名的社会学家斯坦利·米尔格兰姆提出了一个名为“小世界现象(small world phenomenon)”的著名假说,大意是说,任何2个素不相识的人中间最多只隔着6个人,即只用6个人就可以将他们联系在一起,因此他的理论也被称为“六度分离”理论(six degrees of separation)。虽然米尔格兰姆的理论屡屡应验,一直也有很多社会学家对其兴趣浓厚,但是在30多年的时间里,它从来就没有得到过严谨的证明,只是一种带有传奇色彩的假说而已。
Lele对这个理论相当有兴趣,于是,他在HDU里对N个人展开了调查。他已经得到了他们之间的相识关系,现在就请你帮他验证一下“六度分离”是否成立吧。
Lele对这个理论相当有兴趣,于是,他在HDU里对N个人展开了调查。他已经得到了他们之间的相识关系,现在就请你帮他验证一下“六度分离”是否成立吧。
Input
本题目包含多组测试,请处理到文件结束。
对于每组测试,第一行包含两个整数N,M(0<N<100,0<M<200),分别代表HDU里的人数(这些人分别编成0~N-1号),以及他们之间的关系。
接下来有M行,每行两个整数A,B(0<=A,B<N)表示HDU里编号为A和编号B的人互相认识。
除了这M组关系,其他任意两人之间均不相识。
对于每组测试,第一行包含两个整数N,M(0<N<100,0<M<200),分别代表HDU里的人数(这些人分别编成0~N-1号),以及他们之间的关系。
接下来有M行,每行两个整数A,B(0<=A,B<N)表示HDU里编号为A和编号B的人互相认识。
除了这M组关系,其他任意两人之间均不相识。
Output
对于每组测试,如果数据符合“六度分离”理论就在一行里输出"Yes",否则输出"No"。
Sample Input
8 7 0 1 1 2 2 3 3 4 4 5 5 6 6 7 8 8 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 0
Sample Output
Yes Yes
题解:注意大于7;
代码:
1 #include<stdio.h> 2 int map[100][100]; 3 int main(){ 4 int N,M,flot,p1,p2; 5 while(~scanf("%d%d",&N,&M)){ 6 for(int i=0;i<N;++i)for(int j=0;j<N;++j)if(i!=j)map[i][j]=map[j][i]=100;else map[i][j]=0; 7 while(M--){ 8 scanf("%d%d",&p1,&p2); 9 map[p1][p2]=map[p2][p1]=1; 10 } 11 for(int i=0;i<N;++i){ 12 for(int j=0;j<N;++j){ 13 for(int k=0;k<N;++k){ 14 map[j][k]=map[j][i]+map[i][k]<map[j][k]?map[j][i]+map[i][k]:map[j][k]; 15 } 16 } 17 }flot=1; 18 for(int i=0;i<N;++i){ 19 for(int j=0;j<N;++j){ 20 if(map[i][j]>7){//最开始的匹配多了一所以是大于7 21 flot=0;break; 22 } 23 } 24 if(!flot)break; 25 } 26 if(flot)puts("Yes"); 27 else puts("No"); 28 } 29 return 0; 30 }
dijkscra:
1 #include<stdio.h> 2 #include<string.h> 3 #define MIN(x,y)(x<y?x:y) 4 const int INF=0x3f3f3f3f; 5 const int MAXN=110; 6 int map[MAXN][MAXN]; 7 int vis[MAXN],d[MAXN]; 8 int N,M,ans; 9 void initial(){ 10 memset(d,INF,sizeof(d)); 11 memset(vis,0,sizeof(vis)); 12 ans=1; 13 } 14 int dijskra(int s,int e){ 15 initial(); 16 d[s]=0; 17 int k; 18 while(true){ 19 k=-1; 20 for(int i=0;i<N;i++){ 21 if(!vis[i]&&(k==-1||d[i]<d[k]))k=i; 22 } 23 if(k==-1)break; 24 vis[k]=1; 25 for(int i=0;i<N;i++){ 26 d[i]=MIN(d[i],d[k]+map[k][i]); 27 } 28 } 29 return d[e]; 30 } 31 int main(){ 32 int a,b; 33 while(~scanf("%d%d",&N,&M)){ 34 memset(map,INF,sizeof(map)); 35 while(M--){ 36 scanf("%d%d",&a,&b); 37 map[b][a]=map[a][b]=1; 38 } 39 for(int i=0;i<N;i++){ 40 for(int j=i+1;j<N;j++){ 41 if(dijskra(i,j)>7){ 42 ans=0;break; 43 } 44 } 45 if(!ans)break; 46 } 47 if(ans)puts("Yes"); 48 else puts("No"); 49 } 50 return 0; 51 }
并查集求深度,但是wa。。。。
代码:
1 #include<stdio.h> 2 #include<string.h> 3 const int MAXN=1010; 4 int pre[MAXN]; 5 int dep[MAXN]; 6 int N,flot; 7 void initial(){ 8 for(int i=0;i<N;i++){ 9 pre[i]=i; 10 dep[i]=0; 11 } 12 flot=1; 13 } 14 int find(int x){ 15 int temp=pre[x]; 16 if(x==pre[x])return x; 17 pre[x]=find(pre[x]); 18 dep[x]+=dep[temp]; 19 return pre[x]; 20 } 21 void merge(int x,int y){ 22 int f1,f2; 23 f1=find(x);f2=find(y); 24 // printf("%d %d\n",f1,f2); 25 if(f1!=f2){ 26 pre[f2]=f1; 27 dep[f1]++; 28 } 29 } 30 int main(){ 31 int M; 32 int a,b; 33 while(~scanf("%d%d",&N,&M)){ 34 initial(); 35 while(M--){ 36 scanf("%d%d",&a,&b); 37 merge(a,b); 38 } 39 for(int i=0;i<N;i++){ 40 printf("%d",dep[i]); 41 if(dep[i]>7)flot=0; 42 } 43 if(flot)puts("Yes"); 44 else puts("No"); 45 } 46 return 0; 47 }
SPFA:
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 const int INF=0x3f3f3f3f; 6 const int MAXN=110; 7 const int MAXM=420; 8 int head[MAXM]; 9 int dis[MAXN],vis[MAXN],used[MAXN]; 10 queue<int >dl; 11 struct Edge{ 12 int from,to,value,next; 13 }; 14 Edge edg[MAXM]; 15 int N,M,ednum,flot; 16 void initial(){ 17 while(!dl.empty())dl.pop(); 18 memset(dis,INF,sizeof(dis)); 19 memset(used,0,sizeof(used)); 20 } 21 void add(int u,int v,int value){ 22 Edge E={u,v,value,head[u]}; 23 edg[ednum]=E; 24 head[u]=ednum++; 25 } 26 void get(){ 27 int a,b,c; 28 while(M--){ 29 scanf("%d%d",&a,&b); 30 add(a,b,1); 31 add(b,a,1); 32 } 33 } 34 void SPFA(int sx){ 35 initial(); 36 dis[sx]=0;vis[sx]=1; 37 dl.push(sx); 38 while(!dl.empty()){ 39 int k=dl.front(); 40 dl.pop(); 41 vis[k]=0; 42 for(int i=head[k];i!=-1;i=edg[i].next){ 43 int v=edg[i].to; 44 if(dis[k]+edg[i].value<dis[v]){ 45 dis[v]=dis[k]+edg[i].value; 46 if(!vis[v]){ 47 vis[v]=1; 48 dl.push(v); 49 } 50 } 51 } 52 } 53 } 54 55 int main(){ 56 while(~scanf("%d%d",&N,&M)){ 57 flot=1; 58 memset(head,-1,sizeof(head)); 59 ednum=0; 60 get(); 61 // SPFA(0); 62 //for(int i=0;i<N;i++)printf("%d ",dis[i]);puts(""); 63 for(int i=0;i<N;i++){ 64 SPFA(i); 65 for(int j=0;j<N;j++){ 66 if(dis[j]>7){ 67 flot=0;break; 68 } 69 } 70 } 71 if(flot)puts("Yes"); 72 else puts("No"); 73 } 74 return 0; 75 }