#27. 丛林中的路

本文深入探讨了Kruskal算法在解决热带岛屿Lagrishan道路维护问题中的应用,通过实例讲解如何利用最小生成树理论和贪心算法找到最优路径,以最小化每月的维修费用。

【题目描述】:

热带岛屿Lagrishan的首领现在面临一个问题:几年前,一批外援资金被用于维护村落之间的道路,但日益繁茂的丛林无情的侵蚀着村民的道路,导致道路维修开销巨大,长老会不得不放弃部分道路的维护。已经知道了每条路每个月的维修费用(单位为aacms)。现在长老会需要提出一种方案,即需要保证村落之间都可以互相到达,又要将每个月的道路维修费用控制在最小。村子编号为从A到I。上图右侧显示的方案最小维修开销为216 aacms每月。

【输入描述】:

输入包含1~50个数据集,最后一行为0.每个数据集第一行为村落数目n, 1 < n < 27,依次用字母表的前n个字母标记。接下来有n-1行,每行的第一个数据便是按字母顺序排列的村子编号(不包括最后一个村庄)。每个村庄后面的数据k代表该村庄通往编号在其之后的村庄的道路数目,如A 2 B 12 I 25,代表A村庄有2个编号在A之后的村庄和其相连。若k大于0,k后面会依次给出这k个村庄的编号以及各自到起始村庄的道路维修费用,如A 2 B 12 I 25,代表A和B之间道路维修费用为12, A和I之间道路维修费用为25(维修费用为不超过100的正整数).路的总数目不超过75条,每个村庄到其他村庄不会有超过15条路(包括编号在其之前和之后的)。

【输出描述】:

每个数据集有一个输出:针对解决方案每个月维修道路的小费用。

提示:蛮力算法虽能找出解决方案,但将会超出时间限制。

【样例输入】:

9
A 2 B 12 I 25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35
3
A 2 B 10 C 40
B 1 C 20
0

【样例输出】:

216
30

【时间限制、数据范围及描述】:

时间:1s 空间:64M

interesting!这道题目!一看就是一道最小生成树的例题哎,典型的贪心思想。

Kruskal算法

求加权连通图的最小生成树的算法。kruskal算法总共选择n- 1条边,(共n个点)所使用的贪心准则是:从剩下的边中选择一条不会产生环路的具有最小耗费的边加入已选择的边的集合中。注意到所选取的边若产生环路则不可能形成一棵生成树。kruskal算法分e 步,其中e 是网络中边的数目。按耗费递增的顺序来考虑这e 条边,每次考虑一条边。当考虑某条边时,若将其加入到已选边的集合中会出现环路,则将其抛弃,否则,将它选入。

由于本题要使用并查集来将两棵树并到一起去,所以,这个方面的知识必不可少~

code:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int N = 1005;
int fa[N];
int n;
struct edge
{
    int u;
    int v;
    int w;
}e[N];
bool cmd(edge x, edge y)
{
    return x.w < y.w;
}
int find(int x)
{
	if(fa[x]==x)
		return x;
	else
		return fa[x]=find(fa[x]);
}
bool Union(int a,int b)
{
	int x=find(a);
	int y=find(b);
	if(x!=y)
	{
		fa[x]=y;
		return true;
	}
	return false;
}

int main()
{
	freopen("51.in","r",stdin);
	freopen("51.out","w",stdout);
	while(scanf("%d\n",&n)&&n!=0)//\n一定要有,,不然的话,死循环,没有输出,很惨的我为了这个调试了好久....
	{
		//scanf("%d",&n);
	//	if(n==0)
		char a1,a3;
        int a2,a4;
		int t=0;
		for(int i=1;i<n;i++)
		{
			scanf("%c %d ",&a1,&a2);//这里
			for(int j=1;j<=a2;j++)
			{
				scanf("%c %d ",&a3,&a4);//和这里,%d后面一定要有空格
				e[++t].u=a1-'A'+1;
				e[t].v=a3-'A'+1;
				e[t].w=a4;
			}	
		}
		for(int i=1;i<=n;i++)
		fa[i]=i;
		sort(e+1,e+1+t,cmd);
		int ans=0;
		for(int i=1;i<=t;i++)
		{
			if(Union(e[i].u,e[i].v))
			{
				ans+=e[i].w;;
			}
		}
		printf("%d\n",ans);
	}
    return 0;
}

写的我头皮发麻 ..........

# ========== 数据预处理 ========== import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from mpl_toolkits.mplot3d import Axes3D from matplotlib.animation import FuncAnimation def preprocess_data(file_path): """ 数据预处理函数 :param file_path: 数据文件径 :return: 处理后的DataFrame """ # 读取数据 df = pd.read_csv(file_path) # 数据清洗 df = df.dropna(subset=[&#39;latitude&#39;, &#39;longitude&#39;, &#39;acq_date&#39;]) df[&#39;acq_date&#39;] = pd.to_datetime(df[&#39;acq_date&#39;]) # 时间范围筛选(2019年9月-2020年2月) mask = (df[&#39;acq_date&#39;] >= &#39;2019-09-01&#39;) & (df[&#39;acq_date&#39;] <= &#39;2020-02-28&#39;) df = df.loc[mask] # 特征工程 df[&#39;year&#39;] = df[&#39;acq_date&#39;].dt.year df[&#39;month&#39;] = df[&#39;acq_date&#39;].dt.month df[&#39;day&#39;] = df[&#39;acq_date&#39;].dt.day # 异常值处理 df = df[(df[&#39;confidence&#39;] >= 30) & (df[&#39;confidence&#39;] <= 100)] return df # ========== 主程序 ========== if __name__ == "__main__": # 数据预处理 cleaned_df = preprocess_data(&#39;fire_archive_M6_96619.csv&#39;) # 设置可视化风格 plt.style.use(&#39;ggplot&#39;) sns.set_palette("husl") # ========== 可视化部分 ========== # 1. 散点图(地理分布) plt.figure(figsize=(14, 8)) scatter = plt.scatter( cleaned_df[&#39;longitude&#39;], cleaned_df[&#39;latitude&#39;], c=cleaned_df[&#39;confidence&#39;], cmap=&#39;YlOrRd&#39;, alpha=0.6, edgecolors=&#39;w&#39;, s=40 ) plt.colorbar(scatter, label=&#39;置信度&#39;) plt.title(&#39;2019-2020澳大利亚丛林大火地理分布&#39;, fontsize=14) plt.xlabel(&#39;经度&#39;, fontsize=12) plt.ylabel(&#39;纬度&#39;, fontsize=12) plt.tight_layout() plt.savefig(&#39;scatter_plot.png&#39;, dpi=300) plt.close() # 2. Hexbin热力图(替代Folium) plt.figure(figsize=(14, 8)) hb = plt.hexbin( cleaned_df[&#39;longitude&#39;], cleaned_df[&#39;latitude&#39;], gridsize=100, cmap=&#39;YlOrRd&#39;, mincnt=1, alpha=0.9 ) plt.colorbar(hb, label=&#39;火灾密度&#39;) plt.title(&#39;火灾点密度分布&#39;, fontsize=14) plt.xlabel(&#39;经度&#39;, fontsize=12) plt.ylabel(&#39;纬度&#39;, fontsize=12) plt.tight_layout() plt.savefig(&#39;hexbin_heatmap.png&#39;, dpi=300) plt.close() # 3. 时间序列图 plt.figure(figsize=(14, 6)) daily_counts = cleaned_df.resample(&#39;D&#39;, on=&#39;acq_date&#39;).size() daily_counts.plot( kind=&#39;line&#39;, color=&#39;#e34a33&#39;, linewidth=1.5, marker=&#39;o&#39;, markersize=4 ) plt.title(&#39;每日火灾发生趋势&#39;, fontsize=14) plt.xlabel(&#39;日期&#39;, fontsize=12) plt.ylabel(&#39;火灾次数&#39;, fontsize=12) plt.grid(True, alpha=0.3) plt.tight_layout() plt.savefig(&#39;time_series.png&#39;, dpi=300) plt.close() # 4. 月度分布柱状图 month_labels = [&#39;2019-09&#39;, &#39;2019-10&#39;, &#39;2019-11&#39;, &#39;2019-12&#39;, &#39;2020-01&#39;, &#39;2020-02&#39;] plt.figure(figsize=(12, 6)) sns.barplot( x=&#39;month&#39;, y=&#39;confidence&#39;, data=cleaned_df, estimator=np.size, ci=None, palette=&#39;OrRd_r&#39; ) plt.xticks(ticks=range(6), labels=month_labels) plt.title(&#39;月度火灾数量分布&#39;, fontsize=14) plt.xlabel(&#39;月份&#39;, fontsize=12) plt.ylabel(&#39;火灾次数&#39;, fontsize=12) plt.tight_layout() plt.savefig(&#39;monthly_dist.png&#39;, dpi=300) plt.close() # 5. 置信度分布箱线图 plt.figure(figsize=(12, 6)) sns.boxplot( x=&#39;month&#39;, y=&#39;confidence&#39;, data=cleaned_df, palette=&#39;YlOrBr&#39;, showfliers=False ) plt.xticks(ticks=range(6), labels=month_labels) plt.title(&#39;置信度月度分布箱线图&#39;, fontsize=14) plt.xlabel(&#39;月份&#39;, fontsize=12) plt.ylabel(&#39;置信度&#39;, fontsize=12) plt.tight_layout() plt.savefig(&#39;confidence_boxplot.png&#39;, dpi=300) plt.close() # 6. 3D地形图 fig = plt.figure(figsize=(16, 10)) ax = fig.add_subplot(111, projection=&#39;3d&#39;) scatter_3d = ax.scatter( cleaned_df[&#39;longitude&#39;], cleaned_df[&#39;latitude&#39;], cleaned_df[&#39;confidence&#39;], c=cleaned_df[&#39;frp&#39;], cmap=&#39;hot&#39;, s=20, alpha=0.7 ) ax.set_xlabel(&#39;经度&#39;, fontsize=12) ax.set_ylabel(&#39;纬度&#39;, fontsize=12) ax.set_zlabel(&#39;置信度&#39;, fontsize=12) plt.title(&#39;3D火灾特征分布图&#39;, fontsize=14) fig.colorbar(scatter_3d, label=&#39;辐射功率 (FRP)&#39;) plt.tight_layout() plt.savefig(&#39;3d_plot.png&#39;, dpi=300) plt.close() # 7. 昼夜分布环形图 daynight = cleaned_df[&#39;daynight&#39;].value_counts() plt.figure(figsize=(10, 10)) plt.pie( daynight, labels=[&#39;日间&#39;, &#39;夜间&#39;], colors=[&#39;#ff9999&#39;, &#39;#66b3ff&#39;], autopct=&#39;%1.1f%%&#39;, startangle=90, wedgeprops=dict(width=0.4, edgecolor=&#39;w&#39;) ) plt.title(&#39;昼夜火灾分布比例&#39;, fontsize=14) plt.tight_layout() plt.savefig(&#39;daynight_pie.png&#39;, dpi=300) plt.close() # 8. 动态传播图(生成动画) dates = sorted(cleaned_df[&#39;acq_date&#39;].unique()) fig, ax = plt.subplots(figsize=(14, 8)) def animate(i): ax.clear() daily_data = cleaned_df[cleaned_df[&#39;acq_date&#39;] == dates[i]] ax.scatter( daily_data[&#39;longitude&#39;], daily_data[&#39;latitude&#39;], c=daily_data[&#39;frp&#39;], cmap=&#39;Reds&#39;, s=50, alpha=0.7 ) ax.set_title(f&#39;火灾传播动态 ({dates[i].strftime("%Y-%m-%d")})&#39;, fontsize=14) ax.set_xlabel(&#39;经度&#39;, fontsize=12) ax.set_ylabel(&#39;纬度&#39;, fontsize=12) ani = FuncAnimation( fig, animate, frames=len(dates), interval=300, repeat_delay=2000 ) ani.save(&#39;fire_evolution.gif&#39;, writer=&#39;pillow&#39;, fps=3) plt.close() print("所有可视化图表已生成完成")详细解释数据如何进行的处理和每一个可视化图的含义
最新发布
05-11
<think>嗯,用户想要理解Python代码中的数据预处理步骤和各个可视化图表的作用。首先,我需要回忆一下常见的数据处理流程,通常包括数据清洗、转换、归一化、特征工程等步骤。然后针对每个图表类型,比如散点图、热力图、时间序列图等,我得逐一解释它们的用途和应用场景。 用户提到的引用中有关于Matplotlib和Seaborn的内容,特别是热力图和箱线图,这些需要结合库的功能来说明。比如,Seaborn的heatmap()用于显示矩阵数据,可能用于相关性分析;箱线图展示数据分布和离群值。时间序列图可能用Matplotlib的折线图来展示趋势。3D地形图可能涉及更复杂的库如Plotly或Mayavi。 数据预处理的具体步骤可能需要详细展开。例如,数据清洗包括处理缺失值、重复值,数据转换可能涉及标准化、分箱等。特征工程可能会创建新特征或选择重要特征。每个步骤都需要解释清楚,并结合实际例子说明。 另外,用户提到了动态传播动画,这可能使用Matplotlib的animation模块或Plotly的动态图表功能。这部分需要说明如何用代码实现动态效果,以及其适用场景,比如实时数据监控或变化过程展示。 要注意引用中提到的内容,比如引用[2]中的Seaborn高级绘图,引用[3]中Python绘图库的简介。需要将这些信息融入回答,确保准确引用。同时,用户希望了解每个图表的作用,可能需要用实际案例说明,比如热力图用于相关性矩阵,箱线图用于比较类别分布。 还要检查是否有遗漏的图表类型,如环形图,通常是饼图的变种,用于显示比例关系。3D地形图可能用于地理或科学数据可视化。动态传播动画可能用于网络扩散或流行病学模型。 最后,确保回答结构清晰,分步骤讲解预处理,然后逐个图表解释,结合代码示例和引用内容。需要验证每个步骤和图表解释的正确性,避免错误信息。例如,数据预处理的步骤是否全面,每个图表的定义和用途是否准确,是否引用了正确的来源。</think>### 一、Python数据预处理核心步骤 1. **数据清洗** - 处理缺失值:填充均值(`df.fillna()`)或删除空行(`df.dropna()`) - 删除重复值:`df.drop_duplicates()` - 异常值处理:通过$3\sigma$原则或分位数法过滤 - 示例代码: ```python df[&#39;Age&#39;] = df[&#39;Age&#39;].fillna(df[&#39;Age&#39;].median()) df = df[df[&#39;Price&#39;] < df[&#39;Price&#39;].quantile(0.99)] ``` 2. **数据转换** - 标准化:$$x&#39; = \frac{x - \mu}{\sigma}$$(`sklearn.preprocessing.StandardScaler`) - 归一化:$$x&#39; = \frac{x - x_{min}}{x_{max} - x_{min}}$$(`MinMaxScaler`) - 分类变量编码:独热编码(`pd.get_dummies()`)或标签编码 3. **特征工程** - 时间特征提取:拆分日期为年/月/日(`dt.year`) - 特征组合:创建交互项特征(如$收入\times消费频率$) - 降维处理:PCA主成分分析(`sklearn.decomposition.PCA`) --- ### 二、可视化图表作用详解 #### 1. **散点图** - **作用**:展示两个连续变量间的关系,识别聚类或线性趋势 - **代码示例**: ```python plt.scatter(df[&#39;GDP&#39;], df[&#39;Life_Expectancy&#39;], alpha=0.5) ``` - **典型场景**:分析广告投入与销售额相关性[^3] #### 2. **热力图** - **作用**:通过颜色梯度显示矩阵数值,常用于相关系数矩阵 - **代码示例**: ```python sns.heatmap(df.corr(), annot=True, cmap=&#39;coolwarm&#39;) ``` - **进阶应用**:识别多重共线性问题[^2] #### 3. **时间序列图** - **作用**:展示指标随时间变化趋势,检测周期性/异常波动 - **代码示例**: ```python df[&#39;Sales&#39;].plot(figsize=(12,6), title=&#39;Monthly Sales Trend&#39;) ``` - **扩展功能**:添加移动平均线消除噪声 #### 4. **柱状图** - **作用**:比较不同类别的数值差异,支持堆叠显示 - **代码示例**: ```python df.groupby(&#39;Region&#39;)[&#39;Profit&#39;].mean().plot(kind=&#39;bar&#39;) ``` - **特殊变体**:瀑布图展示累计变化过程 #### 5. **箱线图** - **作用**:五数概括(最小值/Q1/中位数/Q3/最大值)及离群值检测 - **代码示例**: ```python sns.boxplot(x=&#39;Class&#39;, y=&#39;Score&#39;, data=df) ``` - **衍生应用**:小提琴图结合分布密度[^2] #### 6. **3D地形图** - **作用**:三维空间数据可视化(如地理高程、化学分子结构) - **代码示例**(使用Plotly): ```python fig = px.scatter_3d(df, x=&#39;X&#39;, y=&#39;Y&#39;, z=&#39;Z&#39;, color=&#39;Value&#39;) fig.show() ``` #### 7. **环形图** - **作用**:改进版饼图,突出中心数据(如完成率) - **代码示例**: ```python plt.pie([70,30], wedgeprops={&#39;width&#39;:0.5}, colors=[&#39;#4CAF50&#39;,&#39;grey&#39;]) ``` #### 8. **动态传播动画** - **作用**:展示网络扩散、疾病传播等动态过程 - **实现方式**: ```python import matplotlib.animation as animation def update(frame): # 更新节点位置和颜色 ani = animation.FuncAnimation(fig, update, frames=100) ``` --- ### 三、流程优化建议 1. 预处理阶段使用`pandas-profiling`自动生成数据质量报告 2. 可视化时遵循「图形完整性」原则:必含标题、坐标标签、图例[^3] 3. 大数据场景优先选择静态图表(性能优于交互式图表)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值