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
Yes Yes
这个题目炸一看是朋友之间的关系.看着题目想了半天一直想的是并查集的操作能否实现.用数组存关系差距离之类的.后来才恍然大悟.距离距离距离...明明是求最短路的题目啊!
这个时候直接翻了模板搞了两发.
这里理解为每个直接认识的人的关系距离为1
例如1 2认识 他俩之间的关系距离就是1
例如2 3也认识 那么2 3关系距离也是1 但是1 3 的关系距离就变成了2.
这里先贴上AC情况:
裸弗洛伊德.
弗洛伊德简单优化.
然后是bellman的队列优化(SPFA)
因为题目中的n最大只有99.所以秒弗洛伊德过是最稳妥最不容易出错的(核心代码就5行而已).如果是在竞赛中 拼手速也是非常重要的.这个时候秒挂弗洛伊德也是非常理智的.
但是平时刷题~还是追求一点完美比较好.
这里先上弗洛伊德的AC代码:
#include<stdio.h> #include<string.h> using namespace std; struct people { int x,y,dis; }a[121212]; int e[1212][1212]; int main() { int n,m; while(~scanf("%d%d",&n,&m)) { for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { e[i][j]=0x1f1f1f1f; } }//图的初始化 for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); e[x][y]=e[y][x]=1; }//图的建立 for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) { if(e[j][k]>(e[j][i]+e[i][k])) e[j][k]=(e[j][i]+e[i][k]); }//核心算法 int ok=0; for(int i=0;i<n;i++)//记住这里整个图都要遍历 (只遍历某个人到其他人的关系距离是WA的,这里读者自己体会一下.) { for(int j=0;j<n;j++) { if(e[i][j]>7) ok=1; } } if(ok==1) printf("No\n"); else printf("Yes\n"); } }
#include<stdio.h> #include<string.h> using namespace std; struct people { int x,y,dis; }a[121212]; int e[1212][1212]; int main() { int n,m; while(~scanf("%d%d",&n,&m)) { for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { e[i][j]=0x1f1f1f1f; } } for(int i=0;i<m;i++) { int x,y; scanf("%d%d",&x,&y); e[x][y]=e[y][x]=1; } for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(e[i][j]==0x1f1f1f1f)continue;//关键优化点. for(int k=0;k<n;k++) { if(e[j][k]>(e[j][i]+e[i][k])) e[j][k]=(e[j][i]+e[i][k]); } } } int ok=0; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { if(e[i][j]>7) ok=1; } } if(ok==1) printf("No\n"); else printf("Yes\n"); } }
然后是spfa
#include<stdio.h> #include<string.h> #include<queue> using namespace std; int head[110],dis[110],vis[110]; int m,n,t; struct people { int u,v,w,next; }s[300]; void spfa(int x) { memset(vis,0,sizeof(vis)); memset(dis,0x1f1f1f1f,sizeof(dis)); dis[x]=0; queue<int >q; q.push(x); while(!q.empty()) { int u=q.front(); q.pop(); vis[u]=0; for(int k=head[u];k!=-1;k=s[k].next) { int v=s[k].v; if(dis[v]>dis[u]+s[k].w) { dis[v]=dis[u]+s[k].w; if(!vis[v]) { vis[v]=1; q.push(v); } } } } } void add(int u,int v,int w)//临接表的建立 { s[t].u=u; s[t].v=v; s[t].w=1; s[t].next=head[u]; head[u]=t++; } int main() { while(~scanf("%d%d",&m,&n)) { memset(head,-1,sizeof(head)); t=0; for(int i=0;i<n;i++) { int a,b; scanf("%d%d",&a,&b); add(a,b,1); add(b,a,1); } int ok=0; for(int i=0;i<m;i++)//每一个人的距离 { spfa(i); for(int j=0;j<m;j++) if(dis[j]>7) { ok=1; break; } if(ok)break; } if(ok)printf("No\n"); else printf("Yes\n"); } }