邦德市

邦德市

1699(最优生成树(并查集)、LCA(倍增))
邦德市有N(编号为1..N)个城市,用M条双向道路连接,每条道路都有一个危险系数。你的任务是回答若干询问,每个询问包含一个起点s和一个终点t,要求找到一条s到t的路径,使得路径上所有边的最大危险系数最小。
第一行一个包含两个整数N和M;接下来的M行,每行包含三个整数:x,y,d(1<=x,y<=N,0<=d<=1 000 000 000),即城市x于城市y有一条危险系数为d的双向道路。下一行一个整数Q,表示有Q个询问;接下来的Q行,每行包含两个整数s,t(s!=t),表示一个询问的起点和终点。
对于每个询问,输出最优路线上所有边的危险系数的最大值。(输入数据保证所有城市是连通的)。
分析

这是一道综合性比较强的题目,反正有些知识点也忘了,干脆就直接顺带回忆

原图中每个点所关联的最小边一定是最小生成树中的边。

下面的行文风格并不是我的风格,是因为我突然抽风像这么写,但是发现并不好写

#include<stack>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define oo 13//通过m计算出oo
const int maxn=10005,maxm=100005;
struct edge{
    int u,v,w;//最优生成树的储存结构是用的这种形式
    friend bool operator<(edge a,edge b){
        return a.w<b.w;
    }
}E[maxm];
int n,m,q,np;
int pa[maxn];
int fa[maxn][20],dep[maxn],dist[maxn][20];//倍增
vector<int>gc[maxn],gw[maxn];//采取相同位置的技巧可以将j和w存在两个数组里面,因为他们位置不会改变,就用不着结构体
void initial(int x){
    for(int i=1;i<=n;i++)
        pa[i]=i;
}
int find(int x){
    if(pa[x]==x)
        return x;
    int root=find(pa[x]);
    return pa[x]=root;
}
bool judge(int x,int y){
    return find(x)==find(y);
}
void merge(int x,int y){
    int px=find(x),py=find(y);
    pa[px]=py;
}
void Init()
{
    int u,v,w;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&u,&v,&w);
        E[i]=(edge){u,v,w};//只用存一边即可 
    }
    sort(E+1,E+m+1); 
}
void shengcheng(){
    initial(n);
    int cnt=0;
    for(int i=1;i<=m;i++){
        int x=E[i].u,y=E[i].v,w=E[i].w;
        if(judge(x,y))continue;
        cnt++;
        merge(x,y);
        gc[x].push_back(y);
        gc[y].push_back(x);
        gw[x].push_back(w);
        gw[y].push_back(w);//储存技巧
        if(cnt==n-1)
            break;
    /*关于这个break写还是不写的问题,其实并没有什么用,时间是差不多的,
    因为排序都已经是mlogm,这点算不了什么,而且cnt++本身也是需要计算时间的,
    只有当m远大于n或者需要判断是否生成了树再加吧*/
    }
}
void DFS(int i,int f,int depp,int w){
    fa[i][0]=f;
    dep[i]=depp;
    dist[i][0]=w;
    for(int j=1;j<=oo;j++){
        fa[i][j]=fa[fa[i][j-1]][j-1];//倍增顺序,现有fa才有dist
        dist[i][j]=max(dist[i][j-1],dist[fa[i][j-1]][j-1]);
    }
    for(int p=0;p<gc[i].size();p++){
        int j=gc[i][p],w=gw[i][p];
        if(j==f)continue;
        DFS(j,i,depp+1,w);
    }
}
int LCA(int u1,int u2){//很有技巧性
    int ret=0;
    if(dep[u1]<dep[u2])
        swap(u1,u2);
    int d=dep[u1]-dep[u2];
    for(int j=oo;j>=0;j--){//j的顺序不能反,下面也是
        if((1<<j)&d){//&这个符号不要搞忘了
            ret=max(ret,dist[u1][j]);//要先改值再倍增,和生成倍增数组是不同
            u1=fa[u1][j];
        }
    }
    if(u1==u2)
        return ret;//这里要改成ret
    for(int j=oo;j>=0;j--){
        if(fa[u1][j]!=fa[u2][j]){
            ret=max(ret,dist[u1][j]);
            ret=max(ret,dist[u2][j]);
            u1=fa[u1][j];
            u2=fa[u2][j];
        }
    }
    return max(ret,max(dist[u1][0],dist[u2][0]));//最后还要判断一次父节点
}//感觉就是回忆了一次LCA呢
void out(){
    for(int i=1;i<=n;i++){
        cout<<i<<":";
        for(int p=0;p<gc[i].size();p++){
            int j=gc[i][p];
            cout<<j<<" "<<gw[i][p]<<"   ";
        }
        cout<<endl;
    }
}
void query(){
    scanf("%d",&q);
    int u1,u2;
    while(q--){
        scanf("%d%d",&u1,&u2);
        LCA(u1,u2);
        printf("%d\n",LCA(u1,u2));
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    Init();
    shengcheng();
    DFS(1,0,1,0);
    query();
    return 0;
}
考虑柔性负荷的综合能源系统低碳经济优化调度【考虑碳交易机制】(Matlab代码实现)内容概要:本文围绕“考虑柔性负荷的综合能源系统低碳经济优化调度”展开,重点研究在碳交易机制下如何实现综合能源系统的低碳化与经济性协同优化。通过构建包含风电、光伏、储能、柔性负荷等多种能源形式的系统模型,结合碳交易成本与能源调度成本,提出优化调度策略,以降低碳排放并提升系统运行经济性。文中采用Matlab进行仿真代码实现,验证了所提模型在平衡能源供需、平抑可再生能源波动、引导柔性负荷参与调度等方面的有效性,为低碳能源系统的设计与运行提供了技术支撑。; 适合人群:具备一定电力系统、能源系统背景,熟悉Matlab编程,从事能源优化、低碳调度、综合能源系统等相关领域研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①研究碳交易机制对综合能源系统调度决策的影响;②实现柔性负荷在削峰填谷、促进可再生能源消纳中的作用;③掌握基于Matlab的能源系统建模与优化求解方法;④为实际综合能源项目提供低碳经济调度方案参考。; 阅读建议:建议读者结合Matlab代码深入理解模型构建与求解过程,重点关注目标函数设计、约束条件设置及碳交易成本的量化方式,可进一步扩展至多能互补、需求响应等场景进行二次开发与仿真验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值