【2021四川省赛】E.Don’t Really Like How The Story Ends(图的dfs遍历)

不喜欢故事的结局

题意:

  • 给一张图,问最少加几条边,能在 dfs 时产生 1 — n 这样的 dfs 序。
  • 考察对图的遍历的理解。

思路:

  • 基本的,对于已给的每个点,延伸出去的边按照子节点编号从小到大排序。这样在遍历时优先遍历小的点。

  • 在某次遍历时,按顺序本该遍历 K 点,但遍历到比 K 大的点,显然此时产生断层,应该加一条边到 K 点上。

  • 模拟这个过程。

C o d e : Code: Code:

#include<bits/stdc++.h>
#include<unordered_map>
#define mem(a,b) memset(a,b,sizeof a)
#define cinios (ios::sync_with_stdio(false),cin.tie(0),cout.tie(0))
#define sca scanf
#define pri printf
#define forr(a,b,c) for(int a=b;a<=c;a++)
#define rfor(a,b,c) for(int a=b;a>=c;a--)
#define endl "\n"
#define oper(a) (operator<(const a& ee)const)
//[博客地址]:https://blog.csdn.net/weixin_51797626?t=1
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;

double DNF = 1e17;
const int N = 100010, M = 200010, MM = N;
int INF = 0x3f3f3f3f, mod = 998244353;
ll LNF = 0x3f3f3f3f3f3f3f3f;
int n, m, k, T, S, D;
vector<int> e[N];
int ans, cnt;

void dfs(int x) {
	if (x == n + 1)return;//边界
	for (auto j : e[x]) {
		if (j < cnt)continue;
		while (j >= cnt)//当且仅当大于时,才产生断层,需要加一条边
		{
			if (j > cnt)ans++;
			dfs(cnt++);
		}
	}
}

void solve() {
	cin >> n >> m;
	forr(i, 1, n) {
		e[i].clear();
	}
	forr(i, 1, m) {
		int a, b;
		cin >> a >> b;
		e[a].push_back(b);
		e[b].push_back(a);
	}
	e[1].push_back(n + 1);//1点处加个哨兵
	//使得 1 能尝试走到 n 以内所有点
	//不加的话,如果 1 是孤立点,就没法往下搜了

	forr(i, 1, n)sort(e[i].begin(), e[i].end());//排序,优先走小的

	ans = 0, cnt = 2;
	dfs(1);
	cout << ans << endl;
}

int main() {
	cinios;

	cin >> T;
	while (T--)solve();

	return 0;
}
/*
3
4 2
1 2
3 4
*/
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值