当前位置: 首页 > news >正文

ABC 394

目录

        E. Palindromic Shortest Path

        F. Alkane


 

 

  

E. Palindromic Shortest Path

        如果正着想,从 i 到 j 有没有回文串路径,太复杂。

        换一种思路,目标是找出所有回文路径,同时记录新增回文路径的两端点对应答案。

        具体方法是从路径长为 0 和 1的所有情况开始扩散,就是 bfs,每次取出一条路径的两个端点 u 和 v,检查有没有一个点 x 到 u 的字符等于 v到一个点 y 的字符,若有并且 x 到 y 还没有答案,则更新 x 到 y的答案。因为路径一定是越来越长,因此第一次更新过的两个点后面不可能再被更新。

        一定要把(i,i)也就是路径长度为 0 的先入队,不能放在循环里入,要确保这些对在队列最前面,也是最先取出。没有了长度为 0 的再开始取长度为 1 的。长度为 0 和 1 的都是预处理进去的。

        

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 105, INF = 1e18;

struct node
{
	int u, v, size;
};

int T, n, cnt, ans[N][N], vis[N][N];
char a[N][N];
queue<node> q;

signed main()
{
	cin >> n;
	for (int i = 1; i <= n; i ++)
		for (int j = 1; j <= n; j ++)
			ans[i][j] = -1;
	for (int i = 1; i <= n; i ++)
		q.push({i, i, 0}), ans[i][i] = 0, vis[i][i] = 1;
	for (int i = 1; i <= n; i ++)
		for (int j = 1; j <= n; j ++)
		{
			cin >> a[i][j];
			if (a[i][j] != '-' && i != j)
				q.push({i, j, 1}), ans[i][j] = 1, vis[i][j] = 1;
		}
	while (!q.empty())
	{
		node t = q.front();	q.pop();
		int u = t.u, v = t.v, s = t.size;
		for (int i = 1; i <= n; i ++)
			if (a[i][u] != '-')
				for (int j = 1; j <= n; j ++)
					if (a[i][u] == a[v][j] && vis[i][j] == 0)
						q.push({i, j, s + 2}), ans[i][j] = s + 2, vis[i][j] = 1;
	}
	for (int i = 1; i <= n; i ++)
	{
		for(int j = 1; j <= n; j ++)
			cout << ans[i][j] << ' ';
		cout << endl;
	}
	return 0;
}

 

 F. Alkane

         画几个烷烃会发现,设度数为 4 的点为主干,有 x 个,则总结点数是 3 * x + 2。因此我们只需要找到主干最多多少个。

        一个点在选出来的子图上能作为主干,那么它在原图上的度数一定大于等于 4。因此我在 dfs 树的时候只看度数大于等于 4 的点。

        dp [ u ] [ 0 ] :u 是根节点,他选 4 个儿子(如果有 4 个儿子的话,不足就是全选)

        dp [ u ] [ 1 ] :u 不是根节点,他还要留一条边给父节点,他只能选最大的 3 个儿子

        dp 里面存的是主干节点的个数,和任何叶子结点都无关!

        那么如何增加选择的子图中一个点只能有 4 个度?就体现在转移方程的时候,对每个主干点只选 3 个或者 4 个儿子。

 

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5 + 5, INF = 1e18;

int T, n, cnt, ans, d[N], vis[N], dp[N][2];
string s;
vector<int> G[N];

void dfs(int u)
{
	vis[u] = 1;
	vector<int> t;
	for (int i = 0; i < G[u].size(); i ++)
	{
		int v = G[u][i];
		if (d[v] >= 4 && vis[v] == 0)
		{
			dfs(v);
			t.push_back(dp[v][1]);
		}
	}
	sort(t.begin(), t.end(), greater<int>());
	for (int i = 0; i < t.size() && i < 3; i ++)	// 不一定有 3 个度数大于等于 4 的儿子 
		dp[u][1] += t[i];
	dp[u][0] = dp[u][1];
	if (t.size() >= 4)
		dp[u][0] += t[3];
}

signed main()
{
	cin >> n;
	for (int i = 1; i <= n; i ++)
		dp[i][1] = 1;
	for (int i = 1; i < n; i ++)
	{
		int u, v;
		cin >> u >> v;
		G[u].push_back(v), G[v].push_back(u);
		d[u] ++, d[v] ++;
	}
	for (int i = 1; i <= n; i ++)
		if (d[i] >= 4 && vis[i] == 0)
			dfs(i);
	for (int i = 1; i <= n; i ++)
		ans = max(ans, dp[i][0]);
	if (ans == 0)
		cout << "-1";
	else
		cout << ans * 3 + 2;
	return 0;
}

相关文章:

  • 使用git管理uniapp项目
  • 轮式机器人在复杂地形中如何选择合适的全局路径规划算法?
  • 为什么办公电脑需要使用企业级杀毒软件?--火绒企业版V2.0
  • 在 macOS 系统上安装 kubectl
  • maven:Maven插件开发实践:动态依赖注入与架构演进说明
  • 快速排序(详解)c++
  • 【Java分布式】基本概念
  • 《模拟器过检测教程:Nox、雷电、Mumu、逍遥模拟器 Magisk、LSposed 框架安装与隐藏应用配置》
  • 模拟与数字电路 寇戈 第三节课后习题
  • 【计网】计算机网络概述
  • 记一次内存泄漏导致的线上超时问题
  • JMH 详细使用
  • 超过DeepSeek、o3,Claude发布全球首个混合推理模型,并将完成新一轮35亿美元融资...
  • 探索AI新前沿,CoT推理赋能文生图!港中文首次提出文生图的o1推理和inference scaling新范式
  • 【嵌入式原理设计】实验五:远程控制翻盖设计
  • 1998-2022年各地级市第一产业占GDP比重数据/(全市)
  • 某住宅小区地下车库安科瑞的新能源汽车充电桩的配电设计与应用方案
  • 从实测看声网:用技术重构直播,为电商创业赋能
  • PhotoShop学习01
  • 自定义mybatis拦截器,在springboot项目中不起作用的解决方法
  • “远践”项目启动公益生态圈,上海青少年公益力量蓬勃生长
  • 国家林草局原党组成员、副局长李春良接受审查调查
  • 高波︱忆陈昊:在中年之前离去
  • 从普通人经历中发现历史,王笛解读《线索与痕迹》
  • 国产水陆两栖大飞机AG600批产首架机完成总装下线
  • 今起公开发售,宁德时代将于5月20日在港股上市