diff --git a/src/20241118/T541156.cpp b/src/20241118/T541156.cpp index 802898f..61e81f1 100644 --- a/src/20241118/T541156.cpp +++ b/src/20241118/T541156.cpp @@ -1,52 +1,26 @@ -#include #include #include -#include #include #include using ll = int64_t; using std::cin, std::cout; -const ll maxn=5e5+5, inf{1l<<(sizeof(inf)*8-4)}; -ll n, k, kd[maxn], mkd[maxn]; +const ll maxn = 5e5+5; +ll n, k, a[maxn]; +std::vector> adj[maxn]; int main(){ std::iostream::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); cin>>n>>k; - std::fill(mkd, mkd+1+k, -inf); - std::vector> adj(n+1, std::vector(n+1,inf)); - for(ll i{1};i<=n;i++){ - cin>>kd[i]; - } + for(ll i{1};i<=n;i++)cin>>a[i]; for(ll i{1};i>u>>v>>w; - adj[u][v]=adj[v][u]=std::min({ - adj[u][v], - adj[v][u], - w - }); - } - for(ll k{1};k<=n;k++){ - for(ll i{1};i<=n;i++){ - for(ll j{1};j<=n;j++){ - adj[i][j]=std::min( - adj[i][j], - adj[i][k]+adj[k][j] - ); - } - } - } - for(ll i{1};i<=n;i++){ - for(ll j{1};j<=n;j++){ - if(i!=j && kd[i]==kd[j]){ - mkd[kd[i]]=std::max(mkd[kd[i]], adj[i][j]); - } - } - } - for(ll i{1};i<=k;i++){ - cout<<(mkd[i]==inf?-1:mkd[i])<<'\n'; + adj[u].emplace_back(v,w); + adj[v].emplace_back(u,w); } + + } \ No newline at end of file diff --git a/src/20241118/T541156.md b/src/20241118/T541156.md new file mode 100644 index 0000000..a17e013 --- /dev/null +++ b/src/20241118/T541156.md @@ -0,0 +1,38 @@ +这段代码中的 `if` 语句主要是用于确保在更新暴龙的红温值 (最大距离) 时判断当前的节点类型与子树中的节点类型之间的关系。具体来说,这里是在处理当前节点 `u` 和子节点 `v` 之间的距离关系,同时考虑了他们的暴龙类型。 + +我们来逐步解析这个 `if` 语句及其包含的逻辑: + +```cpp +if((a[u] == kk || dp[u][kk] > 0) && (a[v] == kk || dp[v][kk] > 0)) { + ans[kk] = max(ans[kk], dp[u][kk] + dp[v][kk] + w); +} +``` + +### 变量说明 + +- `kk`: 表示当前正在处理的暴龙类型的标识符(通常是种类编号)。 +- `a[u]`: 当前节点 `u` 的暴龙类型。 +- `dp[u][kk]`: 从当前节点 `u` 开始的子树中,该暴龙类型 `kk` 的最大距离。 +- `dp[v][kk]`: 从子节点 `v` 开始的子树中,该暴龙类型 `kk` 的最大距离。 +- `w`: 当前节点 `u` 和子节点 `v` 之间的边的权重(即两者之间的距离)。 +- `ans[kk]`: 用于存储当前暴龙类型 `kk` 的红温值(最大距离)。 + +### 逻辑解释 + +1. **类型匹配**: + - `(a[u] == kk || dp[u][kk] > 0)`: + - 这个条件检查当前节点 `u` 是否是类型 `kk` 或者在 `u` 的子树中已经存在类型 `kk` 的暴龙。如果存在,可以考虑将 `u` 和 `v` 之间的距离计算入 `ans[kk]`。 + + - `(a[v] == kk || dp[v][kk] > 0)`: + - 这个条件检查子节点 `v` 是否是类型 `kk` 或者在 `v` 的子树中已经存在类型 `kk` 的暴龙。类似地,如果存在,也可以考虑将 `u` 和 `v` 之间的距离计算入 `ans[kk]`。 + +2. **计算距离**: + - 如果以上两个条件都是满足的,表示 `u` 和 `v` 之间的边可以被计算在类型 `kk` 的红温值中,因此最大距离被更新为: + ```cpp + ans[kk] = max(ans[kk], dp[u][kk] + dp[v][kk] + w); + ``` + - 这里的 `dp[u][kk] + dp[v][kk] + w` 即为通过当前边 `u-v` 连接的所有类型为 `kk` 的暴龙之间的距离。 + +### 总结 + +这个 `if` 判断的作用在于决定是否可以将当前边 `u-v` 的权重 `w` 加入到 `ans[kk]` 中,从而更新当前暴龙类型 `kk` 的最大红温值。这确保了只有在当前节点及其子节点之间具有相同暴龙类型时,才会合并和计算它们之间的边的影响。这样能够更精确地得到不同类型暴龙之间的距离关系。 \ No newline at end of file diff --git a/src/20241118/T541156_old.cpp b/src/20241118/T541156_old.cpp new file mode 100644 index 0000000..802898f --- /dev/null +++ b/src/20241118/T541156_old.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include + +using ll = int64_t; +using std::cin, std::cout; + +const ll maxn=5e5+5, inf{1l<<(sizeof(inf)*8-4)}; +ll n, k, kd[maxn], mkd[maxn]; + +int main(){ + std::iostream::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr); + + cin>>n>>k; + std::fill(mkd, mkd+1+k, -inf); + std::vector> adj(n+1, std::vector(n+1,inf)); + for(ll i{1};i<=n;i++){ + cin>>kd[i]; + } + for(ll i{1};i>u>>v>>w; + adj[u][v]=adj[v][u]=std::min({ + adj[u][v], + adj[v][u], + w + }); + } + for(ll k{1};k<=n;k++){ + for(ll i{1};i<=n;i++){ + for(ll j{1};j<=n;j++){ + adj[i][j]=std::min( + adj[i][j], + adj[i][k]+adj[k][j] + ); + } + } + } + for(ll i{1};i<=n;i++){ + for(ll j{1};j<=n;j++){ + if(i!=j && kd[i]==kd[j]){ + mkd[kd[i]]=std::max(mkd[kd[i]], adj[i][j]); + } + } + } + for(ll i{1};i<=k;i++){ + cout<<(mkd[i]==inf?-1:mkd[i])<<'\n'; + } +} \ No newline at end of file