洛谷 Codeforces CF1829F题解

思路

这道题其实是一个找规律题。我说说自己的一个和别人不太一样的思路。

  • 首先,记录每个节点所连接的节点数以及连向的节点(一个即可)。

  • 由于第三层的节点不再向外连接节点,所以它们所连的节点数必定为一。那么我们只需寻找一个这样的点 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;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值