模板题——图论相关(1)

1.广搜:输出1号点到n号点的最短距离

#include <bits/stdc++.h>

using namespace std;
const int N=100010;
int h[N],e[N],ne[N],idx;
int d[N];
int m,n;
void add(int a,int b)
{
    e[idx]=b;ne[idx]=h[a];h[a]=idx++;
}
int bfs()
{
    queue<int >q;
    memset(d,-1,sizeof(d));
    d[1]=0;
    q.push(1);
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(d[j]==-1)
            {
                d[j]=d[t]+1;
                q.push(j);
            }
        }
    }
    return d[n];
}
int main()
{
    cin>>n>>m;
    memset(h,-1,sizeof(h));
    int a,b;
    for(int i=1;i<=m;i++)
    {
        cin>>a>>b;
        add(a,b);
    }
    cout<<bfs()<<endl;
    return 0;
}

2.拓扑排序:输出任意一个拓扑序列

#include <bits/stdc++.h>

using namespace std;
const int N=100010;
int h[N],e[N],ne[N],idx;
int d[N];
int n,m;
int qq[N];
void add(int a, int b)
{
    e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}

bool topu()
{
    queue<int >q;
    int k=0;
    for(int i=1;i<=n;i++)
    {
        if(!d[i])
        {
                q.push(i);
                qq[k]=i;
                k++;
        }
    }
    while(q.size())
    {
        auto t=q.front();
        q.pop();
        for(int i=h[t];i!=-1;i=ne[i])
        {
            int j=e[i];
            d[j]--;
            if(d[j]==0)
            {
                q.push(j);
                qq[k]=j;
                k++;
            }
        }
    }
    return k==n;
}
int main()
{
    cin>>n>>m;
    memset(h,-1,sizeof(h));
    for(int i=1;i<=m;i++)
    {
        int a,b;
        cin>>a>>b;
        add(a,b);
        d[b]++;
    }
    if(!topu()) puts("-1");
    else
    {
        for(int i=0;i<n;i++)
            printf("%d ",qq[i]);
        puts("");
    }
    return 0;
}

3.朴素迪杰斯特拉算法

#include <bits/stdc++.h>

using namespace std;
const int N=510;
int n,m;
int g[N][N];//稠密图邻接矩阵
int dist[N];//1号点到当前点的距离
bool st[N];
int dijkstra()
{
    memset(dist,0x3f,sizeof dist);//初始化将每个点到1号点的距离设置成无穷大
    dist[1]=0;
    for(int i=0; i<n-1; i++) //将剩余n-1个点依次加入
    {
        int t=-1;
        for(int j=1; j<=n; j++) //在剩余点中寻找当前到1号距离最短的点
            if(!st[j]&&(t==-1||dist[t]>dist[j]))
                t=j;
        for(int j=1; j<=n; j++) //更新加入t点后的最短距离
            dist[j]=min(dist[j],dist[t]+g[t][j]);
        st[t]=true;
    }
    if(dist[n]== 0x3f3f3f3f)
        return -1;
    return dist[n];
}
int main()
{
    scanf("%d%d",&n,&m);
    memset(g,0x3f,sizeof g);
    while(m--)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        g[a][b]=min(g[a][b],c);//ab之间可能有多条路,保留最短的
    }
    printf("%d\n",dijkstra());
    return 0;
}

4.堆维护的迪杰斯特拉算法【优先队列】

#include <bits/stdc++.h>

using namespace std;
typedef pair<int,int >PII;
const int N=1e6+10;//变成稀疏图,使用邻接表
int n,m;
int h[N],w[N],e[N],ne[N],idx;
int dist[N];
bool st[N];
void add(int a,int b,int c)
{
    e[idx]=b;w[idx]=c;ne[idx]=h[a];h[a]=idx++;
}
int dijkstra()
{
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    priority_queue<PII,vector<PII>,greater<PII> > heap;//定义升序优先队列——>小根堆
    heap.push({0,1});
    while(heap.size())
    {
        auto t=heap.top();//当前距离的最小值
        heap.pop();
        int ver=t.second,distance=t.first;
        if(st[ver]) continue;//冗余边
        st[ver]=true;
        for(int i=h[ver];i!=-1;i=ne[i])
        {
            int j=e[i];
            if(dist[j]>dist[ver]+w[i])
            {
                dist[j]=dist[ver]+w[i];
                heap.push({dist[j],j});
            }
        }
    }
    if(dist[n]==0x3f3f3f3f) return -1;
    return dist[n];
}
int main()
{
    scanf("%d%d",&n,&m);
    memset(h,-1,sizeof h);
    while(m--)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }
    cout<<dijkstra()<<endl;
    return 0;
}

5.bellman_ford算法:解决负权边与边数限制的问题

#include <bits/stdc++.h>

using namespace std;
const int N=510,M=10010;
struct Edge
{
    int a,b,c;
}edges[M];
int n,m,k;
int dist[N];
int backup[N];
void bellman_ford()
{
    memset(dist,0x3f,sizeof dist);
    dist[1]=0;
    for(int i=0;i<k;i++)
    {
        memcpy(backup,dist,sizeof dist);
        for(int j=0;j<m;j++)
        {
            auto e=edges[j];
            dist[e.b]=min(dist[e.b],backup[e.a]+e.c);
        }
    }
}
int main()
{
    cin>>n>>m>>k;
    for(int i=0;i<m;i++)
    {
        int a,b,c;
        cin>>a>>b>>c;
        edges[i]={a,b,c};
    }
    bellman_ford();
    if(dist[n]>0x3f3f3f3f/2) puts("impossible");
    else printf("%d\n",dist[n]);
    return 0;
}

内容概要:本文档详细介绍了如何在MATLAB环境下实现CNN-GRU(卷积门控循环单元)混合模型的多输入单输出回归预测。项目旨在通过融合CNN的局部特征提取能力和GRU的时序依赖捕捉能力,解决传统序列模型在处理非线性、高维、多输入特征数据时的局限性。文档涵盖了项目背景、目标、挑战及其解决方案,强调了模型的轻量化、高效性和可视化全流程追踪等特点。此外,还提供了具体的应用领域,如智能电网负荷预测、金融时间序列建模等,并附有详细的代码示例,包括数据加载与预处理、网络结构定义、训练选项设置、模型训练与预测以及结果可视化等步骤。; 适合人群:对深度学习有一定了解,特别是对时间序列预测感兴趣的科研人员或工程师。; 使用场景及目标:①需要处理多输入单输出的非线性回归预测任务;②希望在MATLAB平台上快速实现并优化深度学习模型;③寻求一种高效、轻量且具有良好泛化能力的预测模型应用于实际场景中,如智能电网、金融分析、交通流量预测等领域。; 阅读建议:由于文档内容涉及较多的技术细节和代码实现,建议读者先熟悉CNN和GRU的基本概念,同时掌握MATLAB的基础操作。在阅读过程中,可以结合提供的代码示例进行实践操作,以便更好地理解和掌握CNN-GRU混合模型的构建与应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值