思路
这道题其实是一个找规律题。我说说自己的一个和别人不太一样的思路。
-
首先,记录每个节点所连接的节点数以及连向的节点(一个即可)。
-
由于第三层的节点不再向外连接节点,所以它们所连的节点数必定为一。那么我们只需寻找一个这样的点 u u u,并且通过之前记录的
u u u 连向的节点 v v v(这个唯一的节点一定就是第二层的了),
记录下 v v v 连向的节点数 y ′ y' y′, y ′ y' y′ 减去它与中心点相连的 1,就是所求的 y y y 了。 -
最后来找 x x x。遍历每个点,若当前的节点连接节点数为 y + 1 y+1 y+1,那么就代表这个点亦为第二层的点。记录有几个
点满足这样的要求,可求出第二层点数,即为 x x x。 -
但有一点需特判。若中心点也满足这样的要求,则会被误加一,需判断此时的 x , y x,y x,y 是否令总结点数为 n n n,若不是,则 x x x 需减一。
Code
#include<bits/stdc++.h>
using namespace std;
int n,m;
struct node{
long long cnt;
int to;
}g[100001];
int main(){
int T;
cin >> T;
while(T--) {
memset(g,0,sizeof(g));
cin >> n >> m;
for(int i=1;i<=m;i++) {
int u,v;
cin >> u >> v;
g[u].cnt++;
g[v].cnt++;
g[u].to=v;
g[v].to=u;//记录每个节点所连接的节点数以及连向的节点
}
long long x=0,y=0;
for (int i=1;i<=n;i++) {
if (g[i].cnt==1) {
y=g[g[i].to].cnt-1;//寻找连点数为一的点
break;
}
}
for (int i=1;i<=n;i++) {
if (g[i].cnt-1==y) x++;//计算x
}
if (x*y+x+1!=n) x--;//特判
cout << x << ' ' << y << '\n';
}
return 0;
}