50 years, 50 colors

本文介绍了一种解决最小点覆盖问题的方法,通过构建二分图并利用最大匹配算法求解。具体实现采用深度优先搜索(DFS)进行匹配,详细展示了如何通过遍历节点寻找可能的匹配,并给出了完整的 C++ 代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个题是最小点覆盖

根据定理也就是求二分图的最大匹配(证明没看懂)

就是我们把行拿出来作为左部分,列拿出来作为右部分,然后两者相连的边就代表了原图中的点

#include<iostream>
#include<cstdio>
#include<map>
#include<string.h>
using namespace std;
int un,uv;
map<int,int>m;
const int maxn = 100+10;
int g[maxn][maxn];
int linker[maxn];
int used[maxn];
int n,k;
int res[100];
bool dfs(int u,int t){
    for(int v = 0;v<uv;++v){
        if(g[u][v]==t&&!used[v]){
            used[v] = true;
            if(linker[v]==-1||dfs(linker[v],t)){
            linker[v] = u;
            return true;}
        }
    }
    return false;
}

int hungry(int t){
    int res = 0;
    memset(linker,-1,sizeof(linker));
    for(int u =0;u<un;++u){
        memset(used,false,sizeof(used));
        if(dfs(u,t))res++;
    }
    return res;
}
int main(){
    while(~scanf("%d%d",&n,&k)&&n+k!=0){
            m.clear();
            un = n,uv= n;
        for(int i = 0;i<n;++i){
            for(int j =0;j<n;++j){
                scanf("%d",&g[i][j]);
                m[g[i][j]]=1;
            }
        }

        int h = 0;
        map<int,int>::iterator it;
        for(it = m.begin();it!=m.end();++it){
            if(hungry(it->first)>k){
                res[h++]=it->first;
            }
        }
        if(h==0)
            cout<<-1<<endl;
        else{
                for(int i =0;i<h;++i){
                    if(i)
                        cout<<" "<<res[i];
                    else
                        cout<<res[i];
                }
                cout<<endl;
            }

    }

}

 

这是我我的代码,我想要实现通过折线图的legendopts,也就是折线图的图例配置项来同时控制玫瑰图,从而实现图表之间的交互,请给我一个合理的解决方案,并且给我完整代码from pyecharts.charts import Pie, Timeline, Line, Grid, Page from pyecharts import options as opts from pyecharts.commons.utils import JsCode from pyecharts.components import Table import pandas as pd # 读取 CSV 数据 df = pd.read_csv("年度数据.csv") # 获取指标和年份 indicators = df['指标'].unique() years = sorted(df.columns[1:].tolist()) # 对年份进行排序 # 创建一个字典来存储清洗后的数据 cleaned_data = {'年份': years} # 处理每个教育程度和性别 for indicator in indicators: if "人口数" not in indicator: continue # 提取教育程度和性别 if "男性" in indicator: education_level = indicator.replace('6岁及6岁以上', '').replace('男性人口数(人口抽样调查)(人)', '').strip() gender = '男性' elif "女性" in indicator: education_level = indicator.replace('6岁及6岁以上', '').replace('女性人口数(人口抽样调查)(人)', '').strip() gender = '女性' else: continue # 跳过不相关的指标 # 获取数据并排序 data = df[df['指标'] == indicator].values[0][1:].tolist() # 根据排序后的年份重新排列数据 sorted_data = [x for _, x in sorted(zip(df.columns[1:], data))] # 存储数据 cleaned_data[f"{gender}_{education_level}"] = sorted_data # 将清洗后的数据转换为 DataFrame cleaned_df = pd.DataFrame(cleaned_data) # 修改颜色生成函数 - 男性(蓝色系跨度更大) def generate_blue_colors(n): colors = [] # 从浅蓝到深蓝的更大跨度渐变 r_values = [200, 150, 100, 50, 0] # 红色分量递减 g_values = [230, 180, 130, 80, 30] # 绿色分量递减 b_values = [255, 255, 255, 255, 255] # 蓝色保持高值 for i in range(n): # 确保索引不越界 idx = min(i, len(r_values) - 1) color = f"rgb({r_values[idx]},{g_values[idx]},{b_values[idx]})" colors.append(color) return colors # 修改颜色生成函数 - 女性(以深粉色为基准进行渐变) def generate_soft_pink_colors(n): colors = [] # 以 #C2185B (194,24,91) 为基准的渐变 base_r, base_g, base_b = 194, 24, 91 # 生成从浅粉到深粉的更大跨度渐变 for i in range(n): # 计算渐变因子 (0到1之间) factor = i / (n - 1) if n > 1 else 0 # 从浅色 (接近白色) 到深粉色渐变 r = int(base_r * factor + 255 * (1 - factor)) g = int(base_g * factor + 220 * (1 - factor)) b = int(base_b * factor + 230 * (1 - factor)) color = f"rgb({r},{g},{b})" colors.append(color) return colors # 创建玫瑰图 def create_pie_chart(year_index, years, cleaned_df): current_year = years[year_index] year_data = cleaned_df.iloc[year_index] # 教育程度列表 education_levels = ['未上过学', '小学', '初中', '高中', '大专及以上'] # 计算各教育程度人口数 total_male = 0 total_female = 0 male_education_counts = [] female_education_counts = [] for level in education_levels: male_col = f"男性_{level}" female_col = f"女性_{level}" if male_col in cleaned_df.columns: male_count = year_data[male_col] male_education_counts.append(male_count) total_male += male_count if female_col in cleaned_df.columns: female_count = year_data[female_col] female_education_counts.append(female_count) total_female += female_count # 计算占比,保留两位小数 if total_male != 0: male_percentages = [round(count / total_male * 100, 2) for count in male_education_counts] else: male_percentages = [0] * len(education_levels) if total_female != 0: female_percentages = [round(count / total_female * 100, 2) for count in female_education_counts] else: female_percentages = [0] * len(education_levels) # 生成蓝色系和浅粉色系颜色列表 num_colors = len(education_levels) blue_colors = generate_blue_colors(num_colors) pink_colors = generate_soft_pink_colors(num_colors) # 创建玫瑰图 pie = ( # Pie(init_opts=opts.InitOpts(width='800px', height='600px', bg_color='white')) # Pie(init_opts=opts.InitOpts()) Pie(init_opts=opts.InitOpts(width='100%', height='100%', bg_color='white')) ) # 添加男性系列并设置蓝色系颜色 pie.add( series_name="男性教育程度占比", data_pair=[(education_levels[i], male_percentages[i]) for i in range(len(education_levels))], radius=["30%", "55%"], center=["30%", "50%"], rosetype="radius", label_opts=opts.LabelOpts(formatter="{b}: {c}%", position="outside"), itemstyle_opts=opts.ItemStyleOpts(color=JsCode( """function(params) { var colors = %s; return colors[params.dataIndex]; }""" % blue_colors )) ) # 添加女性系列并设置浅粉色系颜色 pie.add( series_name="女性教育程度占比", data_pair=[(education_levels[i], female_percentages[i]) for i in range(len(education_levels))], radius=["30%", "55%"], center=["70%", "50%"], rosetype="radius", label_opts=opts.LabelOpts(formatter="{b}: {c}%", position="outside"), itemstyle_opts=opts.ItemStyleOpts(color=JsCode( """function(params) { var colors = %s; return colors[params.dataIndex]; }""" % pink_colors )) ) # 设置提示框样式 - 与折线图相似 tooltip_style = { "trigger": "item", "border_width": 2, "border_color": "#FFEB3B", # 亮黄色边框 "background_color": "rgba(255, 255, 255, 0.8)", # 半透明白色背景 "textstyle_opts": opts.TextStyleOpts(color="black", font_size=12) # 黑色文字 } # 设置全局选项 pie.set_global_opts( title_opts=opts.TitleOpts( title=f"{current_year}教育程度占比(男左女右)", pos_left='center', pos_top='20', title_textstyle_opts=opts.TextStyleOpts(color='black', font_size=16) ), legend_opts=opts.LegendOpts(is_show=False), tooltip_opts=opts.TooltipOpts(**tooltip_style) # 应用提示框样式 ) # 设置系列选项 pie.set_series_opts( label_opts=opts.LabelOpts(formatter="{b}: {c}%") ) return pie # 创建时间轴 - 玫瑰图 timeline_pie = Timeline() timeline_pie.add_schema( play_interval=1000, is_auto_play=True, is_loop_play=False, ) # 为每个年份生成玫瑰图并添加到时间轴 for i in range(len(years)): pie_chart = create_pie_chart(i, years, cleaned_df) timeline_pie.add(pie_chart, str(years[i])) # 准备绘图数据 male_education = {} female_education = {} # 提取教育程度数据 for col in cleaned_df.columns: if col == '年份': continue gender, education_level = col.split('_', 1) if gender == '男性': if education_level != "": # 不要提取总人口数 male_education[education_level] = cleaned_df[col].values.tolist() elif gender == '女性': if education_level != "": # 不要提取总人口数 female_education[education_level] = cleaned_df[col].values.tolist() # 设置颜色主题 # 男性颜色主题(蓝色系) male_colors = [ "#1E88E5", # 蓝色 "#0D47A1", # 深蓝色 "#42A5F5", # 浅蓝色 "#64B5F6", # 更浅的蓝色 "#90CAF9" # 最浅的蓝色 ] # 女性颜色主题(粉色系) female_colors = [ "#EC407A", # 粉红色 "#C2185B", # 深粉色 "#F48FB1", # 浅粉色 "#F8BBD0", # 更浅的粉色 "#FFCDD2" # 最浅的粉色 ] # 创建一个函数来生成单个年份的图表组合 def create_combined_chart(year_index, years, male_education, female_education): current_year = years[year_index] start = max(0, year_index - 4) end = year_index + 1 current_years = years[start:end] # 设置男性提示框样式 - 亮黄色边框 male_tooltip_style = { "trigger": "axis", "border_width": 2, "border_color": "#FFEB3B", # 亮黄色边框 "background_color": "rgba(255, 255, 255, 0.8)", # 背景颜色和透明度 "textstyle_opts": opts.TextStyleOpts(color="black", font_size=12) # 文本样式 } # 设置女性提示框样式 - 亮粉色边框 female_tooltip_style = { "trigger": "axis", "border_width": 2, "border_color": "#FF4081", # 亮粉色边框 "background_color": "rgba(255, 255, 255, 0.8)", # 背景颜色和透明度 "textstyle_opts": opts.TextStyleOpts(color="black", font_size=12) # 文本样式 } # 创建男性教育程度折线图 male_line = ( Line() .add_xaxis(current_years) .set_global_opts( legend_opts=opts.LegendOpts(pos_top="2%", pos_left="center"), tooltip_opts=opts.TooltipOpts(**male_tooltip_style), yaxis_opts=opts.AxisOpts(name="人口数"), title_opts=opts.TitleOpts(title="男性人口受教育程度", pos_left="left") ) ) # 为男性教育程度设置不同的颜色 for index, (level, data) in enumerate(male_education.items()): current_data = data[start:end] male_line.add_yaxis( series_name=level, y_axis=current_data, is_symbol_show=True, is_smooth=True, stack="stack1", itemstyle_opts=opts.ItemStyleOpts(color=male_colors[index % len(male_colors)]), # 设置线条颜色 areastyle_opts=opts.AreaStyleOpts( color=male_colors[index % len(male_colors)], opacity=0.5 ), label_opts=opts.LabelOpts(is_show=False), # 隐藏教育程度线条上的标签 ) # 添加男性人口总数线条,修改样式使其更有趣 if '男性_' in cleaned_df.columns: male_total = cleaned_df['男性_'].values.tolist() # 直接从清洗后的数据中获取 current_male_total = male_total[start:end] male_line.add_yaxis( series_name="男性人口", y_axis=current_male_total, is_symbol_show=True, symbol="circle", # 使用圆形标记点 symbol_size=10, # 增大标记点大小 is_smooth=True, linestyle_opts=opts.LineStyleOpts( width=4, # 增加线条宽度 type_="dashed", # 使用虚线样式 color="#efb6d3", # 设置线条颜色为粉色 ), label_opts=opts.LabelOpts( is_show=False, # 隐藏平滑折线图上的标签 ), itemstyle_opts=opts.ItemStyleOpts( color="rgba(239, 182, 211, 0.8)", # 修改气泡颜色为半透明的粉色 border_color="#efb6d3", # 设置气泡边框颜色为粉色 border_width=2 # 设置气泡边框宽度 ), markpoint_opts=opts.MarkPointOpts( # 添加特殊标记点 data=[ opts.MarkPointItem(type_="max", name="最大值"), opts.MarkPointItem(type_="min", name="最小值") ], label_opts=opts.LabelOpts( font_size=14, # 增大文字大小 color="black", # 设置文字颜色 background_color="rgba(255, 255, 255, 0.8)", # 设置文字背景颜色, ) ), markline_opts=opts.MarkLineOpts( # 添加趋势线 data=[opts.MarkLineItem(type_="average", name="平均值")], label_opts=opts.LabelOpts( font_size=14, # 增大文字大小 color="black", # 设置文字颜色 background_color="rgba(255, 255, 255, 0.8)", # 设置文字背景颜色, # formatter=lambda x: "{:.0f}".format(x) ) ), z=5, ) # 创建女性教育程度折线图 female_line = ( Line() .add_xaxis(current_years) .set_global_opts( legend_opts=opts.LegendOpts(pos_top="50%", pos_left="center"), tooltip_opts=opts.TooltipOpts(**female_tooltip_style), yaxis_opts=opts.AxisOpts(name="人口数"), title_opts=opts.TitleOpts(title="女性人口受教育程度", pos_left="left", pos_top="50%") ) ) # 为女性教育程度设置不同的颜色 for index, (level, data) in enumerate(female_education.items()): current_data = data[start:end] female_line.add_yaxis( series_name=level, y_axis=current_data, is_symbol_show=True, is_smooth=True, stack="stack2", itemstyle_opts=opts.ItemStyleOpts(color=female_colors[index % len(female_colors)]), # 使用女性颜色主题 areastyle_opts=opts.AreaStyleOpts( color=female_colors[index % len(female_colors)], # 使用女性颜色主题 opacity=0.5 ), label_opts=opts.LabelOpts(is_show=False), # 隐藏教育程度线条上的标签 ) # 添加女性人口总数线条,修改样式使其更有趣 if '女性_' in cleaned_df.columns: female_total = cleaned_df['女性_'].values.tolist() # 直接从清洗后的数据中获取 current_female_total = female_total[start:end] female_line.add_yaxis( series_name="女性人口", y_axis=current_female_total, is_symbol_show=True, symbol="diamond", # 使用菱形标记点 symbol_size=10, # 增大标记点大小 is_smooth=True, linestyle_opts=opts.LineStyleOpts( width=4, # 增加线条宽度 type_="dotted", # 使用点划线样式 color="#2196F3", # 更鲜艳的颜色 ), label_opts=opts.LabelOpts( is_show=False, # 隐藏平滑折线图上的标签 ), itemstyle_opts=opts.ItemStyleOpts( color="rgba(33, 150, 243, 0.8)", # 修改气泡颜色为半透明的蓝色 border_color="#2196F3", # 设置气泡边框颜色 border_width=2 # 设置气泡边框宽度 ), markpoint_opts=opts.MarkPointOpts( # 添加特殊标记点 data=[ opts.MarkPointItem(type_="max", name="最大值"), opts.MarkPointItem(type_="min", name="最小值") ], label_opts=opts.LabelOpts( font_size=14, # 增大文字大小 color="black", # 设置文字颜色 background_color="rgba(255, 255, 255, 0.8)", # 设置文字背景颜色, ) ), markline_opts=opts.MarkLineOpts( # 添加趋势线 data=[opts.MarkLineItem(type_="average", name="平均值")], label_opts=opts.LabelOpts( font_size=14, # 增大文字大小 color="black", # 设置文字颜色 background_color="rgba(255, 255, 255, 0.8)", # 设置文字背景颜色, # formatter=lambda x: "{:.0f}".format(x) ) ), z=5, ) # 将两个图表组合在一起,并调整它们之间的距离 grid = ( Grid() .add(male_line, grid_opts=opts.GridOpts(pos_bottom="60%")) # 调整底部位置 .add(female_line, grid_opts=opts.GridOpts(pos_top="64%")) # 调整顶部位置 ) return grid # 创建时间轴 - 折线图 timeline_line = Timeline() timeline_line.add_schema( play_interval=1000, is_auto_play=True, is_loop_play=False, ) # 为每个年份生成图表并添加到时间轴 for i in range(len(years)): combined_chart = create_combined_chart(i, years, male_education, female_education) timeline_line.add(combined_chart, str(years[i])) # ====== 创建组合页面 ====== page = Page( layout=Page.DraggablePageLayout, page_title="教育程度数据可视化" ) # 设置页面背景色 page.add( timeline_pie, timeline_line ) # 添加使用说明表格 instruction_table = Table() instruction_table.add( ["图表说明"], [ ["<b>左侧图表:</b>分性别教育程度占比玫瑰图(随时间轴播放)"], ["<b>右侧图表:</b>分性别教育程度人口数变化折线图(随时间轴播放)"], ["<b>交互操作:</b>"], ["1. 拖动图表标题栏可移动位置"], ["2. 拖动图表右下角可调整大小"], ["3. 点击时间轴播放按钮可播放/暂停"], ["4. 鼠标悬停在图表上可查看详细数据"], ["5. 调整布局后点击右上角'保存配置'按钮可保存布局"] ] ) instruction_table.set_global_opts( title_opts=opts.ComponentTitleOpts( title="使用说明", subtitle="操作指南和图表说明" ) ) # 添加表格到页面 page.add(instruction_table) # 渲染页面 page.render("教育程度数据可视化.html") print("组合图表已生成,文件名为 '教育程度数据可视化.html'")
06-07
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值