Assign the task HDU - 3974 (dfs + 线段树)

题意:题意就是给你一颗树,然后如果你给一节点上赋值,那么他下面的所以子节点都会被赋上这个值,现在有两个操作:1 查询某个节点上的值,2.修改某个节点上的值 (注意他下面的值也会改变)

点击打开链接

思路:就是,我们在树上跑一边dfs然后给这颗树上的每个节点都重新编号,得到一个high数组和一个low数组,其实high数组表示的是区间左端点,low数组表示的区间右端点


之后就是对区间进行的操作了 ,然后查询就单点查询就好了 ,相通了还是挺简单的上代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#define lson l , m ,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn =  50200;
int sum[maxn<<2] , high[maxn] , low[maxn];  //high 管辖的头结点  low 尾节点
int head[maxn] , cnt , vis[maxn],tot , p[maxn] , n ,lazy[maxn<<2];

struct node
{
	int to,next;
}edg[maxn<<1];

void add(int u ,int v)
{
	edg[cnt].to=v;
	edg[cnt].next = head[u];
	head[u] = cnt++;
}

void init()
{
	memset(head,-1,sizeof(head));
	memset(lazy,0,sizeof(lazy));
	memset(sum,0,sizeof(sum));
	memset(high,0,sizeof(high));
	memset(low,0,sizeof(low));
	cnt = 0 ;
	tot = 0 ;
	for(int i = 1 ; i <= n ;i++)
	{
		p[i] = i;
	}
}
int getf(int v)
{
	return p[v] = v ? p[v] : getf(v);
}
void dfs(int v)
{
	if(vis[v]) return ;
	high[v] = ++tot;
	for(int i = head[v] ; i!=-1 ; i = edg[i].next)
	{
		int p = edg[i].to;
		dfs(p);
	}
	low[v] = tot;
}

void pushdown(int rt)
{
	if(lazy[rt] != 0 )
	{
		lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt];
		sum[rt<<1] = lazy[rt];
		sum[rt<<1|1] = lazy[rt];
	//	printf("sum[rt] = %d  sum[rt<<1] = %d  lazy = %d\n",sum[rt<<1] , sum[rt<<1|1] , lazy[rt]);
		lazy[rt] = 0;
	}
}

void build(int l , int r , int rt)
{
	sum[rt] = 0;
	if(l == r) return ;
	int m = (l + r)>>1;
	build(lson);
	build(rson);
}

void update(int L , int R , int add , int l , int r , int rt)
{
	if(l>=L&&R>=r)
	{
		sum[rt] = add;
		lazy[rt] = add;
		return ;
	}
	pushdown(rt);
	int m = (r+l)>>1;
	if(m>=L)
	{
		update(L,R,add,lson);
	}
	if(R>m)
	{
		update(L,R,add,rson);
	}
}
/*int query(int L ,int R ,int l ,int r , int rt)
{
	if(l>=L&&R>=r)
	{
		return sum[rt];
	}
	pushdown(rt);
	int m = (l + r)>>1;
	int ret = 0;
	if(m>=L)
	{
		ret = query(L,R,lson);
	}
	if(R>m)
	{
		ret = query(L,R,rson);
	}
	return ret;
}*/
int query(int p, int l,int r ,int rt)
{
	if(l == r) return sum[rt];
	pushdown(rt);
	int m = (l+r)>>1;
	if(m>=p) query(p,lson);
	else query(p,rson);
}
int main() 
{
	int t;
	int flag = 0 ;
	char op[2];
	scanf("%d",&t);
	while(t--)
	{
		int a,b;
		scanf("%d",&n);
		init();
		for(int i = 0 ; i < n-1 ; i++)
		{
			scanf("%d%d",&a,&b);//建边的时候要换一下
			add(b,a);
			int da = getf(a);
			int db = getf(b);//并查集 是为了找到树的根节点在哪里 
			if(da!=db)
			{
				p[da] = db;
			}
		}
		int p = getf(1);//根节点
		dfs(p);//从根节点开始深搜
		int m;
		scanf("%d",&m);
		printf("Case #%d:\n",++flag);
		for(int i = 0  ; i < m ; i++)
		{
			scanf("%s",op);
			if(op[0] == 'C')
			{
				scanf("%d",&a);
				int ans = query(high[a] , 1 , n , 1);
				printf("%d\n",ans ? ans : -1);
			}
			else if(op[0] == 'T')
			{
				scanf("%d%d",&a,&b);
			//	printf("a = %d  b = %d\n",a,b);
				update(high[a] , low[a] , b , 1 , n , 1);
			}		
		}
	}
}
/*
1
5
4 3
3 2
1 3
5 2
5 
C 3 
T 2 1
C 3
T 3 2
C 3
*/


以下是K-means++多维数据聚类分析的Matlab代码,以及模型性能评估方法: ```matlab % Load data data = load('data.mat'); % Number of clusters to find k = 3; % Initialize centroids using K-means++ centroids = init_centroids(data, k); % Run K-means algorithm for i = 1:100 % Assign each data point to the nearest centroid idx = find_closest_centroids(data, centroids); % Compute new centroids based on the assigned data points centroids = compute_centroids(data, idx, k); end % Plot the clusters plot_clusters(data, idx, k); % Function to initialize centroids using K-means++ function centroids = init_centroids(data, k) % Randomly choose the first centroid centroids = data(randi(size(data, 1)), :); % Choose each subsequent centroid with probability proportional to its % distance from the closest existing centroid for i = 2:k dists = pdist2(data, centroids); [~, D] = min(dists, [], 2); P = min(D, [], 1).^2; P = P / sum(P); centroids(i, :) = data(find(rand < cumsum(P), 1), :); end end % Function to assign each data point to the nearest centroid function idx = find_closest_centroids(data, centroids) dists = pdist2(data, centroids); [~, idx] = min(dists, [], 2); end % Function to compute new centroids based on the assigned data points function centroids = compute_centroids(data, idx, k) for i = 1:k centroids(i, :) = mean(data(idx == i, :), 1); end end % Function to plot the clusters function plot_clusters(data, idx, k) colors = ['r', 'g', 'b', 'y', 'm', 'c']; hold on; for i = 1:k scatter(data(idx == i, 1), data(idx == i, 2), colors(i)); end hold off; end ``` 对于模型性能评估,可以使用以下指标: 1. SSE(Sum of Squared Errors):表示所有数据点到其所属簇中心的距离之和,越小越好; 2. Silhouette coefficient:表示聚类结果的紧密度和分离度,范围在-1到1之间,越接近1越好。 可以使用以下代码计算这些指标: ```matlab % SSE dists = pdist2(data, centroids); [~, idx] = min(dists, [], 2); sse = sum(min(dists, [], 2)); % Silhouette coefficient s = silhouette(data, idx); sc = mean(s); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值