【树的直径+并查集】 codeforces 455C - Civilization

本文介绍了一种算法,用于在预处理每个集合的最长路径(树的直径)后,通过两次BFS找到集合之间的最长路径,并在更新直径时采用特定公式。此算法适用于需要在多个集合中查找最长路径的场景。

先预处理出每个集合的最长路,就是树的直径,可以两次BFS找。。然后合并集合更新最长路就是在dep[a],dep[b],(dep[a]+1)/2+(dep[b]+1)/2+1三者取最大。。

#include <iostream>  
#include <queue>  
#include <stack>  
#include <map>  
#include <set>  
#include <bitset>  
#include <cstdio>  
#include <algorithm>  
#include <cstring>  
#include <climits>  
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 300005
#define maxm 100005
#define eps 1e-10
#define mod 3
#define INF 1e9
#define lowbit(x) (x&(-x))  
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid  
#define rson o<<1 | 1, mid+1, R  
typedef long long LL;
//typedef int LL;
using namespace std;

int n, m;
int f[maxn], dep[maxn];
vector<int> vec[maxn];
vector<int> g[maxn];
set<int> s[maxn];
queue<int> q;
int vis[maxn];
int dis[maxn];

int find(int x)
{
	return x == f[x] ? x : f[x] = find(f[x]);
}

void debug(void)
{
	for(int i = 1; i <= n; i++)
		printf("AA  %d  BB\n", dep[i]);
}
int bfs(int u)
{
	int d = g[f[u]].size(), mx;
	for(int i = 0; i < d; i++) dis[g[f[u]][i]] = INF;
	q.push(u), dis[u] = 0, mx = u;
	while(!q.empty()) {
		int x = q.front();
		q.pop();
		int d = vec[x].size();
		for(int i = 0; i < d; i++) {
			if(dis[vec[x][i]] > dis[x] + 1) {
				dis[vec[x][i]] = dis[x] + 1;
				q.push(vec[x][i]);
				if(dis[vec[x][i]] > dis[mx])
					mx = vec[x][i];
			}
		}
	}
	return mx;
}
void init(void)
{
	int q, u, v, aa, bb;
	scanf("%d%d%d", &n, &m, &q);
	for(int i = 0; i <= n; i++) f[i] = i;
	while(m--) {
		scanf("%d%d", &u, &v);
		vec[u].push_back(v);
		vec[v].push_back(u);
		aa = find(u);
		bb = find(v);
		if(aa == bb) continue;
		else if(aa < bb) f[bb] = aa;
		else f[aa] = bb;
	}
	m = q;
	for(int i = 1; i <= n; i++) find(i);
	for(int i = 1; i <= n; i++) {
		s[f[i]].insert(i);
		g[f[i]].push_back(i);
	}
	for(int i = 1; i <= n; i++) {
		if(f[i] == i) {
			int tmp = bfs(i);
			tmp = bfs(tmp);
			dep[i] = dis[tmp];
		}
	}
}
void work(void)
{
	int k, a, b, aa, bb;
	while(m--) {
		scanf("%d", &k);
		if(k == 1) {
			scanf("%d", &a);
			aa = find(a);
			printf("%d\n", dep[aa]);
		}
		else {
			scanf("%d%d", &a, &b);
			aa = find(a);
			bb = find(b);
			if(aa == bb) continue;
			int tmp = (dep[aa] + 1)/2 + (dep[bb] + 1)/2 + 1;
			tmp = max(tmp, max(dep[aa], dep[bb]));
			if(aa > bb) f[aa] = bb, dep[bb] = tmp;
			else f[bb] = aa, dep[aa] = tmp;
		}
	}
}
int main(void)
{
	init();
	work();
	return 0;
}


内容概要:本研究聚焦于绿电直连型电氢氨园区的优化运行,提出一种集成绿色电力直接供给、电解水制氢及氢气合成氨工艺的综合能源系统架构。通过建立包含风光发电、电解槽、氨合成反应器、储氢罐、电网交互及多类型负荷在内的系统模型,综合考虑绿电直供优先、能量梯级利用与多能互补原则,构建以系统综合运行成本最小化为目标的优化调度模型。研究采用Matlab与Python工具进行算法求解和仿真分析,利用实际气象与负荷数据完成案例验证,评估了不同运行策略下系统的经济性、可再生能源消纳能力与碳减排效益,为新型电氢氨一体化园区的规划与运行提供了理论依据和技术支撑。; 适合人群:具备一定电力系统、新能源或化工背景的研究生、科研人员及从事综合能源系统规划与优化工作的工程技术人员。; 使用场景及目标:①用于科研学习,理解电--氨多能转换系统的建模与优化方法;②为工业园区的低碳化、智能化改造提供技术参考与决策支持;③作为开发类似综合能源管理系统的理论基础。; 阅读建议:此资源包含完整的模型代码、数据与论文,使用者应结合代码仔细研读论文中的模型构建部分,重点关注目标函数与约束条件的设计逻辑,并尝试修改参数进行仿真,以深入掌握优化算法在实际系统中的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值