0
点赞
收藏
分享

微信扫一扫

2.14总结

非衣所思 2022-02-14 阅读 58
c语言

1.上午四个小时

完成了两个题目。

建立双向图需要注意,添加边的时候第一次是一个方向(a,b,c),第二次是相反的方向(b,a,c),边的起点和终点要交换。一开始就卡在这里。

P1629 邮递员送信

P1629 邮递员送信 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路

邮递员每次只能送一个包裹,所以需要多次返回邮局,因此要建立双向的图,然后就利用迪杰斯特拉算法的标准版就可以了。

代码实现

#include<bits/stdc++.h>
using namespace std;
const int N=100001;
const int zz=0x7fffffff;
const int M=500001;
int n,m,s=1,cnt=0,e,f,g,h;
int head[N],dist[N];
bool vis[N];
long long sum;
struct edge
{
    int to;
    int weight;
    int next;
} edge[M];
struct node
{
    int idex;
    int way;
    bool operator<(const node &x) const
    {
        return x.way<way;
    }
};
void addedge(int a,int b,int v)
{
    cnt++;
    edge[cnt].to=b;
    edge[cnt].weight=v;
    edge[cnt].next=head[a];
    head[a]=cnt;
}
void dij(int s)
{
    for(int i=1; i<=2*n; i++)
    {
        vis[i]=false;
        dist[i]=zz;
    }
    dist[s]=0;
    priority_queue<node> q;
    q.push({s,0});
    while(q.size())
    {
        int bb=q.top().idex;
        q.pop();
        if(vis[bb])
            continue;
        vis[bb]=true;
        for(int i=head[bb]; i; i=edge[i].next)
        {
            if(!vis[edge[i].to]&&dist[edge[i].to]>dist[bb]+edge[i].weight)
            {
                dist[edge[i].to]=dist[bb]+edge[i].weight;
                q.push({edge[i].to,dist[edge[i].to]});
            }
        }
    }
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1; i<=m; i++)
    {
        scanf("%d %d %d",&f,&g,&h);
        addedge(f,g,h);
        addedge(g+n,f+n,h);
    }
    dij(1);
    for(int i=2; i<=n; i++)
        sum+=dist[i];
    dij(1+n);
    for(int i=2+n; i<=2*n; i++)
        sum+=dist[i];
    printf("%lld",sum);
    return 0;
}

P1339 [USACO09OCT]Heat Wave G

P1339 [USACO09OCT]Heat Wave G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路

首先建立无向图,然后套用迪杰斯特拉算法的弱化版,但要注意有点不同就是这题多了终点,还有是双向的。

代码实现

#include<bits/stdc++.h>
using namespace std;
int head[10001];
int n,m,s,t,o,p,q,cnt;
bool vis[10001];
long long dist[10001];
struct Edge
{
    int to;
    int weight;
    int next;
}edge[500001];
void addedge(int a,int b,int v)
{
    cnt++;
    edge[cnt].to=b;
    edge[cnt].weight=v;
    edge[cnt].next=head[a];
    head[a]=cnt;
}
void dij()
{
    for(int i=1;i<=n;i++)
    {
        dist[i]=2147483647;
        vis[i]=false;
    }
    dist[s]=0;
    int idex=s;
    while(!vis[idex])
    {
        vis[idex]=true;
        for(int i=head[idex];i!=0;i=edge[i].next)
        {
            if(!vis[edge[i].to]&&dist[edge[i].to]>dist[idex]+edge[i].weight)
            {
                dist[edge[i].to]=dist[idex]+edge[i].weight;
            }
        }
        int Min=2147483647;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&Min>dist[i])
            {
                Min=dist[i];
                idex=i;
            }
        }
    }
    printf("%d",dist[t]);
}
int main()
{
    scanf("%d %d %d %d",&n,&m,&s,&t);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %d",&o,&p,&q);
        addedge(o,p,q);
        addedge(p,o,q);
    }
    dij();
    return 0;
}

2.下午三个小时晚上一个半小时

看了讲解堆二叉树、堆优化、优先队列的视频,复习了迪杰斯特拉算法、弗洛伊德算法。

举报

相关推荐

0 条评论