115. 给树染色

博主边看视频边敲代码,感觉自己还不具备单独完成提高组+题目的能力。文中以一个贪心(greedy)题为例,通过假设不同节点选择顺序计算成本,得出结果取决于节点平均值,做法是找出非根节点最大节点并入父节点,还给出了代码实现步骤。

 

 

继续看yan老哥的视频    还是一边看yan老哥视频一边敲代码 总感觉自己现在还不具备单独过提高组+题目的能力  写代码5分钟调试半小时   不是这错就是那错  ;这是个greedy题 而且要找出一个顺序        ;那么我们假设子节点b其父节点a    

以及一个八杆子打不着的节点c      ;   如果先选b,a  那么  cost为  a+2b+3c;   

如果先选c 则为  c+2a+3b;  结果是看c 和 (a+b)/2的关系 

那么推广到一般情况    结果就是看那一坨节点的平均值  ;    所以我们不停的找出非根节点的最大节点  ;然后将其并入父节点  ,最终根节点就是答案;   

做法 ;

1   begin:f[i]=i;  最初各自为一组  

2  接下来每次会将两组点合并,将其中一组点接在另一组点的后面    

 

 

 代码 

#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <bitset>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <list>
#include <map>
#include <set>
#include<iomanip>
#include <bits/stdc++.h>
/***************************************/
#define  ll  long long
#define int64 __int64
#define PI 3.1415927
#define INF 99999
#define MAXN 1000010
using namespace std;

 struct node
 {
     int father, size ,sum;//父节点     子树个数  权值和
     double avg;
 }nodes[1010];     int n,root;

int find()//求当前这个点权值的非根节点
{
 double avg=0;  int ans=-1;


 for(int i=1;i<=n;i++)
 {
       if(i!=root&&nodes[i].avg>avg)//根节点无法往上和并
       {
          avg=nodes[i].avg;
          ans=i;
       }
 }

    return ans;
}

  int main()

{

       cin>>n>>root; int res=0;
       for(int i=1;i<=n;i++)
       {    cin>>nodes[i].sum;
           nodes[i].avg = nodes[i].sum;
        nodes[i].size = 1;
        res += nodes[i].sum;
       }
         int a,b;
         for(int i=0;i<n-1;i++)
         {
             cin>>a>>b;
nodes[b].father=a ;

         }
         for(int i=0;i<n-1;i++)
         {
              int ver=find();
              int father_baba =nodes[ver ].father;
              res+= nodes[ver].sum*nodes[father_baba].size;  //更新答案
              nodes [ver].avg=-1;//已经被遍历
             for(int  j=1 ;j<=n;j++)//合并   删边 连结点
             {
                  if(nodes[j].father== ver)
                  {
                  nodes[j].father =father_baba ;

             } 
             }
 nodes[father_baba].sum+=nodes[ver].sum;
             nodes[father_baba].size+=nodes[ver].size;
               nodes[father_baba].avg=(double)nodes[father_baba].sum/nodes[father_baba].size ;

         }  cout<<res<<endl;

    return 0;
}

  

<think>我们讨论的是在Midway.js中实现代码染色功能。代码染色(Code Coloring)通常指的是在日志中为不同级别的日志信息添加颜色,以便于开发者快速识别日志级别(如错误、警告、信息等)。在Midway.js中,我们可以通过配置日志的格式化器(formatter)来实现。 Midway.js使用`@midwayjs/logger`作为日志模块,它基于Winston,因此我们可以利用Winston的格式化功能来实现代码染色。 ### 实现步骤 #### 1. 安装依赖 确保已经安装了`@midwayjs/logger`和`winston`(通常Midway自带,如果没有则安装): ```bash npm install @midwayjs/logger winston ``` #### 2. 配置日志格式化 在配置文件(如`src/config/config.default.ts`)中,我们可以通过`midwayLogger`配置项来自定义日志格式,包括颜色。 ```typescript import { MidwayConfig } from '@midwayjs/core'; import { format } from 'winston'; export default { midwayLogger: { default: { // 其他配置... format: format.combine( format.colorize(), // 启用颜色 format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.printf(({ level, message, timestamp }) => { return `${timestamp} [${level}] ${message}`; }) ), // 注意:如果使用文件传输,颜色代码可能会被写入文件,通常控制台输出才需要颜色 transports: [ // 控制台输出 { type: 'console', // 可以在这里单独为控制台设置格式 // 因为文件不需要颜色,所以颜色格式化通常只加在控制台传输上 }, // 文件输出(不需要颜色) // ...其他传输配置 ] } } } as MidwayConfig; ``` #### 3. 自定义格式化器(可选) 如果你需要更复杂的颜色方案,可以自定义一个格式化器。例如,为不同日志级别设置不同的颜色: ```typescript import { format } from 'winston'; const customFormat = format.combine( format.colorize({ all: true, // 为整个消息着色 level: true, // 为日志级别着色 message: true, // 为消息着色 colors: { info: 'green', warn: 'yellow', error: 'red', debug: 'blue' } }), format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.printf(({ level, message, timestamp }) => { return `${timestamp} [${level}] ${message}`; }) ); ``` 然后在配置中引用这个自定义格式化器。 #### 4. 配置传输器(Transports) 注意,颜色代码通常只在控制台(console)输出时有用,写入文件时颜色代码反而会干扰阅读。因此,我们通常只在控制台传输器上启用颜色。 在配置中,我们可以为不同的传输器设置不同的格式: ```typescript export default { midwayLogger: { default: { // ...其他配置 transports: [ { type: 'console', format: customFormat // 使用带颜色的格式 }, { type: 'file', dir: './logs', fileLogName: 'app.log', format: format.combine( // 文件传输不使用颜色 format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.printf(({ level, message, timestamp }) => { return `${timestamp} [${level}] ${message}`; }) ) } ] } } } as MidwayConfig; ``` #### 5. 使用日志 在代码中,正常使用日志即可: ```typescript import { Controller, Get, Inject } from '@midwayjs/core'; import { Logger } from '@midwayjs/logger'; @Controller('/') export class HomeController { @Inject() logger: Logger; @Get('/') async home() { this.logger.debug('This is a debug message'); this.logger.info('This is an info message'); this.logger.warn('This is a warning message'); this.logger.error('This is an error message'); return 'Hello Midway!'; } } ``` ### 效果 运行应用后,在控制台将看到不同级别的日志以不同颜色显示。 ### 注意事项 1. 颜色功能依赖于`winston`的`format.colorize`,它会在字符串中添加ANSI颜色代码,这些代码在支持ANSI的控制台(如终端)中会显示颜色,但在不支持的环境(如文件)中会显示为乱码。 2. 在生产环境中,通常我们只希望控制台输出带颜色,而文件日志则不需要颜色代码。 ### 生产环境配置建议 在生产环境中,我们可能希望根据环境变量来决定是否启用颜色(例如,只在非生产环境启用颜色)。我们可以通过条件判断来设置格式: ```typescript // src/config/config.default.ts import { MidwayConfig } from '@midwayjs/core'; import { format } from 'winston'; const isProd = process.env.NODE_ENV === 'production'; export default { midwayLogger: { default: { // ...其他配置 transports: [ { type: 'console', format: isProd ? format.combine( format.timestamp(), format.simple() ) : format.combine( format.colorize(), format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), format.printf(({ level, message, timestamp }) => { return `${timestamp} [${level}] ${message}`; }) ) }, // 文件传输... ] } } } as MidwayConfig; ``` 这样,在生产环境下控制台输出将不包含颜色,而在开发环境下则包含颜色。 ### 引用说明 在Midway.js中,日志模块的配置灵活且强大,通过结合Winston的格式化功能,我们可以轻松实现代码染色[^1][^4]。 §§相关问题§§ 1. 如何在Midway.js中自定义日志输出格式? 2. 如何在Midway.js中实现日志文件按天分割? 3. Midway.js如何将日志同时输出到控制台和文件? 4. 如何在Midway.js中为不同环境配置不同的日志级别?</think>在 Midway.js 中实现代码染色功能(即根据代码执行路径或条件标记不同逻辑分支),可以通过以下步骤配置和实现: ### 一、核心实现方案 #### 1. 使用 AOP 切面编程(推荐) ```typescript // src/aspect/trace.aspect.ts import { Aspect, IMethodAspect, JoinPoint, Provide } from '@midwayjs/decorator'; @Provide() @Aspect([/* 要染色的类或方法 */]) export class TraceAspect implements IMethodAspect { async around(point: JoinPoint) { const start = Date.now(); const ctx = point.ctx; // 请求上下文 try { // 执行前染色 ctx.trace = { path: `${point.target.constructor.name}.${point.methodName}`, startTime: start, tags: ['important'] // 自定义染色标签 }; const result = await point.proceed(...point.args); // 执行原方法 // 执行后染色 ctx.trace.duration = Date.now() - start; ctx.trace.success = true; return result; } catch (err) { // 错误染色 ctx.trace.error = err.message; ctx.trace.success = false; throw err; } } } ``` #### 2. 配置染色作用域 ```typescript // src/configuration.ts import { Configuration } from '@midwayjs/core'; import { TraceAspect } from './aspect/trace.aspect'; @Configuration({ imports: [/* 其他模块 */], importConfigs: [/* 配置文件 */], }) export class MainConfiguration { async onReady() { // 注册染色切面 this.app.getAspectManager().bindClass(TraceAspect, [ UserController, // 指定控制器 PaymentService, // 指定服务 /^Order.*Service/ // 正则匹配 ]); } } ``` ### 二、染色数据收集与可视化 #### 1. 日志集成染色数据 ```typescript // src/config/config.default.ts export default { midwayLogger: { default: { format: info => { const trace = info.ctx?.trace || {}; return `${info.timestamp} [${info.level}] [${trace.path || '-'}] ${info.message} | tags=${trace.tags?.join(',')} duration=${trace.duration || 0}ms`; } } } } ``` #### 2. 染色数据存储(Redis示例) ```typescript // src/service/trace.service.ts import { Provide, Inject } from '@midwayjs/core'; import { RedisService } from '@midwayjs/redis'; @Provide() export class TraceService { @Inject() redisService: RedisService; async record(traceData: object) { await this.redisService.lpush( 'code_traces', JSON.stringify({ ...traceData, timestamp: Date.now() }) ); } } // 在切面中调用 ctx.traceService.record(ctx.trace); ``` ### 三、染色数据可视化 #### 1. 添加染色端点 ```typescript // src/controller/trace.controller.ts import { Controller, Get, Inject } from '@midwayjs/core'; import { TraceService } from '../service/trace.service'; @Controller('/trace') export class TraceController { @Inject() traceService: TraceService; @Get('/') async getTraces() { const traces = await this.traceService.getRecentTraces(); return { success: true, data: traces }; } } ``` #### 2. 前端展示示例(React) ```jsx function TraceViewer() { const [traces, setTraces] = useState([]); useEffect(() => { fetch('/trace').then(res => res.json()) .then(data => setTraces(data)); }, []); return ( <div> {traces.map(trace => ( <div key={trace.id} className={trace.success ? 'success' : 'error'}> <h3>{trace.path}</h3> <p>Duration: {trace.duration}ms</p> <div>{trace.tags.map(tag => <span className="tag">{tag}</span>)}</div> </div> ))} </div> ); } ``` ### 四、生产环境增强建议 1. **染色采样率控制**(避免性能损耗) ```typescript // 在切面中添加 if (Math.random() < 0.1) { // 10%采样率 ctx.trace.sampled = true; // 记录染色数据 } ``` 2. **集成 OpenTelemetry** ```bash npm install @opentelemetry/api @midwayjs/otel ``` ```typescript // configuration.ts import { otel } from '@midwayjs/otel'; @Configuration({ imports: [otel], importConfigs: [/* config */] }) export class MainConfiguration {} ``` 3. **染色数据过滤** ```typescript // 只染色耗时超过100ms的请求 async around(point: JoinPoint) { if (ctx.trace?.duration > 100) { ctx.trace.slow = true; } } ``` ### 五、验证染色效果 1. 发起测试请求: ```bash curl http://localhost:7001/user/profile ``` 2. 查看染色日志: ``` 2023-08-15 14:30 [INFO] [UserController.getProfile] Request completed | tags=important duration=45ms ``` 3. 访问染色端点: ``` http://localhost:7001/trace ``` ### 六、注意事项 1. **性能影响**:染色操作会增加少量性能开销,建议生产环境开启采样率控制 2. **数据安全**:避免记录敏感信息(密码、token等) 3. **作用域控制**:使用 `@Scope(ScopeEnum.Request)` 确保每次请求独立上下文[^1] 4. **存储选择**:高并发场景建议使用 Redis 或 Elasticsearch 存储染色数据[^5] > 通过代码染色功能,开发者可以清晰识别关键执行路径和性能瓶颈,结合日志分割功能[^1],能够构建完整的可观测性体系,显著提升系统维护效率[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值