P7929 [COCI2021-2022#1] Logičari
P7929 [COCI2021-2022#1] Logičari
[P7929 COCI2021-2022#1] Logičari - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题目大意
给定一棵
思路
我们考虑一棵普通的树看看怎么解决。
很明显是一个树形
我们先
然后我们考虑不合法的情况:
1、
2、
3、
在遇到
我们考虑转移。
设
设
设
如果
否则
code
#include <bits/stdc++.h>
#define LL long long
#define fu(x , y , z) for(x = y ; x <= z ; x ++)
using namespace std;
const int inf = 1e9 + 5 , N = 1e5 + 5;
int hd[N] , cnt , s , t , vis[N] , flg , fs , ft , out , n;
LL f[N][2][2] , w[N][2];
struct E {
int to , nt;
} e[N << 1];
void add (int x , int y) { e[++cnt].to = y , e[cnt].nt = hd[x] , hd[x] = cnt; }
void dfs (int x , int fa) {
int y;
vis[x] = 1;
for (int i = hd[x] ; i ; i = e[i].nt) {
y = e[i].to;
if (y == fa) continue;
if (vis[y]) flg = i;
else dfs (y , x);
}
}
LL dp (int x , int fa , int a , int b) {
if (f[x][a][b]) return f[x][a][b];
int y;
LL sum = 0 , ans = inf;
for (int i = hd[x] ; i ; i = e[i].nt) {
y = e[i].to;
if ((y == fa) || (i == flg) || ((i ^ 1) == flg)) continue;
if (y == t) {
if ((a && fs) || (b && ft) || (!a && !fs && out < 3)) return inf;
w[y][ft] = dp (y , x , ft , (fs | a));
w[y][!ft] = inf;
sum += w[y][0];
}
else {
w[y][0] = dp (y , x , 0 , a);
sum += w[y][0];
if (!b) w[y][1] = dp (y , x , 1 , a);
}
}
if (b) return f[x][a][b] = sum + a;
for (int i = hd[x] ; i ; i = e[i].nt) {
y = e[i].to;
if ((y == fa) || (i == flg) || ((i ^ 1) == flg)) continue;
ans = min (ans , sum - w[y][0] + w[y][1]);
}
return f[x][a][b] = ans + a;
}
int main () {
int x , y;
LL ans;
cnt = 1;
scanf ("%d" , &n);
for (int i = 1 ; i <= n ; i ++) {
scanf ("%d%d" , &x , &y);
add (x , y) , add (y , x);
}
dfs (1 , 0);
s = e[flg].to , t = e[flg ^ 1].to;
for (int i = hd[t] ; i ; i = e[i].nt) ++out;
// cout << out << " " << t;
// return 0;
fs = ft = 0;
ans = dp (s , 0 , 0 ,0);
memset (f , 0 , sizeof (f));
fs = 1 , ft = 0;
ans = min (ans , dp (s , 0 , 1 , 0));
memset (f , 0 , sizeof (f));
fs = 0 , ft = 1;
ans = min (ans , dp (s , 0 , 0 , 1));
memset (f , 0 , sizeof (f));
fs = ft = 1;
ans = min (ans , dp (s , 0 , 1 , 1));
if (ans <= 1ll * n) printf ("%lld" , ans);
else printf ("-1");
return 0;
}
如果人生会有很长,愿有你的荣耀永不散场
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 周边上新:园子的第一款马克杯温暖上架
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
· 使用C#创建一个MCP客户端