暑假集训周总结第三篇(8.6-8.13)

链式前向星

int h[N], e[N], ne[N], idx;  // e相当于val,ne相当于nxt,具体请参考上方的超链接

int w[N];  // 用来存储每条边的权重

// 向图中添加a到b的有向边,权重为c

void add(int a, int b, int c) {

    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;

}

int main() {

    memset(h, -1, sizeof(h));  // 使用链式前向星必须进行初始化

    int n, m;

    cin >> n >> m;

    while (m--) {

        int a, b, c;

        cin >> a >> b >> c;

        add(a, b, c);

    }

    return 0;

}

最短路

#include <bits/stdc++.h>

using namespace std;

#define endl "\n"

#define int long long

typedef pair<int,int> PII;

const int N=2e5+10;

int e[N],ne[N],h[N],idx,w[N];

int d[N];

bool st[N];

int n,m;

void add(int a,int b,int c)

{

    e[idx]=b;

    ne[idx]=h[a];

    w[idx]=c;

    h[a]=idx++;

}

int dijkstra()

{

    memset(d,0x3f,sizeof(d));

    d[1]=0;

    priority_queue<PII,vector<PII> ,greater<PII> >heap;

    heap.push({0,1});

    while(heap.size())

    {

        auto tt=heap.top();

        heap.pop();

        int ver=tt.second,dis=tt.first;

        if(st[ver])continue;

        for(int i=h[ver];i!=-1;i=ne[i])

        {

            int j=e[i];

            if(d[j]>dis+w[i])

            {

                d[j]=dis+w[i];

                heap.push({d[j],j});

            }

        }

        

    }if(d[n]==0x3f3f3f3f3f3f3f3f)return -1;

        return d[n];

}

void solve()

{

    cin>>n>>m;

    int x,y,z;

    memset(h,-1,sizeof(h));

    while(m--)

    {

        cin>>x>>y>>z;

        add(x,y,z);

    }

    int t=dijkstra();

    cout<<t<<endl;

    return ;

    

}

signed main()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

    int T = 1;

    //cin >> T;

    while (T--)

        solve();

    return 0;

}

Bf算法

#include<bits/stdc++.h>

using namespace std;

#define endl "\n"

#define int  long long

const int N=505,M=100010;

int n,m,k;

int dis[N],backup[N];//存距离的

struct node 

{

    int a,b,c;

}bian[M];//存边,不管bf算法是可以硬存存边的

int bellman_ford()

{

    memset(dis,0x3f,sizeof(dis));//初始化距离数组

    dis[1]=0;//初始化

    for(int i=1;i<=k;i++)//表达在距离不超过i条边的情况下能走到的最短路的值

    {

        memcpy(backup,dis,sizeof(dis));//备份,就是以防串联更新

        for(int j=1;j<=m;j++)

        {

            int aa=bian[j].a;

            int bb=bian[j].b;

            int cc=bian[j].c;//取边

            dis[bb]=min(dis[bb],backup[aa]+cc);//比较,有点像DP

        }

    }

    if(dis[n]>(0x3f3f3f3f3f3f3f3f)/2)//用>比较是因为负边可能会把-INF更新成-INF-n,像是-INF-2

    {

        return -99999;

    }

    else

    {

        return dis[n];

    }

}

void solve()

{

    cin>>n>>m>>k;

    int x,y,z;

    for(int i=1;i<=m;i++)

    {

        cin>>x>>y>>z;

        bian[i].a=x;

        bian[i].b=y;

        bian[i].c=z;

    }

    int ans=bellman_ford();

    if(ans==-99999)

    {

        cout<<"impossible"<<endl;

    }

    else

    {

        cout<<ans<<endl;

    }

    

}

signed main()

{

    ios::sync_with_stdio(0);

    cin.tie(0);

    cout.tie(0);

    int T=1;

    //cin>>T;

    while(T--)

    {

        solve();

        return 0;

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值