0
点赞
收藏
分享

微信扫一扫

最短路的所有题解

日月同辉9908 2022-02-15 阅读 47

目录

租用游艇

Clear And Present Danger S

Heat Wave G

单源最短路径(弱化版)

邮递员送信

单源最短路径(标准版)


租用游艇

 - [P1359 租用游艇](租用游艇 - 洛谷)

#include<stdio.h>
#define inf 0x3f3f3f3f
int e[201][201];
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i==j)e[i][j]=0;
            else e[i][j]=inf;
        }
    }
    for(int i=1;i<=n-1;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            scanf("%d",&e[i][j]);
        }
    }
    for(int k=1;k<=n;k++)
        for(int i=1;i<=n;i++)
           for(int j=1;j<=n;j++)
               if(e[i][j]>e[i][k]+e[k][j])e[i][j]=e[i][k]+e[k][j];
     printf("%d",e[1][n]);
    return 0;
}

Clear And Present Danger S

- [P2910 [USACO08OPEN]Clear And Present Danger S]

([USACO08OPEN]Clear And Present Danger S - 洛谷)

#include<stdio.h>
int e[101][101],a[10001];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
    scanf("%d",&a[i]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
           scanf("%d",&e[i][j]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            for(int k=1;k<=n;k++)
               if(e[j][k]>e[j][i]+e[i][k])
                  e[j][k]=e[j][i]+e[i][k];
    int ans=0;
    for(int i=2;i<=m;i++)
        ans+=e[a[i-1]][a[i]];
    printf("%d",ans);
    return 0;
}

Heat Wave G

- [P1339 [USACO09OCT]Heat Wave G]([USACO09OCT]Heat Wave G - 洛谷)

#include<stdio.h>
#define inf 0x3f3f3f3f
int e[2501][2501],book[2501],dis[2501];
int main()
{
    int n,m,s,t;
    scanf("%d%d%d%d",&n,&m,&s,&t);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i==j)e[i][j]=0;
            else e[i][j]=inf;
        }
    }
    for(int i=1;i<=m;i++)
    {
        int t1,t2,t3;
        scanf("%d%d%d",&t1,&t2,&t3);
        if(t3<e[t1][t2])//易漏!!!
        {
           e[t1][t2]=t3;
           e[t2][t1]=t3;
        }
    }
    for(int i=1;i<=n;i++)
    {
        dis[i]=e[s][i];
    }
    book[s]=1;
    for(int i=1;i<=n-1;i++)
    {
        int min=inf,u;
        for(int j=1;j<=n;j++)
        {
            if(book[j]==0&&dis[j]<min)
            {
                min=dis[j];
                u=j;
            }
        }
        book[u]=1;
        for(int j=1;j<=n;j++)//更新与u相连点的dis[]
        {
            if(e[u][j]<inf)
            {
              if(dis[j]>dis[u]+e[u][j])
              dis[j]=dis[u]+e[u][j];
            }
        }
    }
    printf("%d",dis[t]);
    return 0;
}

单源最短路径(弱化版)

- [P3371 【模板】单源最短路径(弱化版)](【模板】单源最短路径(弱化版) - 洛谷)

代码实现如下:

#include<stdio.h>
#include<string.h>
#define inf 2147483647
struct Node
{
    int to;
    int v;
    int next;
} edge[500001];
int book[10001],dis[10001],head[10001],cnt;
int n,m,s;
// 链式前向星
void add(int a,int b,int c)
{
    cnt++;//下标
    edge[cnt].to=b;
    edge[cnt].v=c;
    edge[cnt].next=head[a];
    head[a]=cnt;
}
void dij()
{
    int idx=s;//把起点看做扩展点
    while(1)
    {
        book[idx]=1;
        for(int i=head[idx]; i!=-1; i=edge[i].next)
        {
            int a=idx,b=edge[i].to,v=edge[i].v;
            if(dis[b]>dis[a]+v)//我这里没标记!!!!
                dis[b]=dis[a]+v;
        }
        int min=inf;
        for(int i=1; i<=n; i++)
        {
            if(book[i]==0&&min>dis[i])
            {
                min=dis[i];
                idx=i;
            }
        }
        if(book[idx])break;//所有点的最短路径都求出来了
    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1; i<=n; i++)
    {
        head[i]=-1;
        dis[i]=inf;
    }
    dis[s]=0;
    for(int i=1; i<=m; i++)
    {
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        add(a,b,c);
    }
    dij();
    for(int i=1; i<=n; i++)
    printf("%d ",dis[i]);
    return 0;
}

邮递员送信

- [P1629 邮递员送信](邮递员送信 - 洛谷)

#include<stdio.h>
#define inf 0x3f3f3f3f
int e[1001][1001],dis[1001],book[1001];
int n,m,ans;
void dij()
{
    for(int i=1;i<=n-1;i++)
    {
        int min=inf,u;
        for(int j=1;j<=n;j++)
        {
            if(book[j]==0&&dis[j]<min)
            {
                min=dis[j];
                u=j;
            }
        }
        book[u]=1;
        for(int j=1;j<=n;j++)//更新与u相连点的dis[]
        {
            if(e[u][j]<inf)
            {
              if(dis[j]>dis[u]+e[u][j])
              dis[j]=dis[u]+e[u][j];
            }
        }
    }
}
void over()//翻转
{
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            int temp=0;
            temp=e[i][j];
            e[i][j]=e[j][i];
            e[j][i]=temp;
        }
    }
}
int main()
{

    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(i==j)e[i][j]=0;
            else e[i][j]=inf;
        }
    }
    for(int i=1;i<=m;i++)
    {
        int t1,t2,t3;
        scanf("%d%d%d",&t1,&t2,&t3);
        if(e[t1][t2]>t3)e[t1][t2]=t3;
    }
    for(int i=1;i<=n;i++)
        dis[i]=e[1][i];
    dij();
    for(int i=1;i<=n;i++)
    {
        ans+=dis[i];
    }
    over();
    for(int i=1;i<=n;i++)
    book[i]=0;//要把标记重新清0
    for(int i=1;i<=n;i++)
    dis[i]=e[1][i];
    dij();
    for(int i=1;i<=n;i++)
    {
        ans+=dis[i];
    }
    printf("%d",ans);
    return 0;
}

单源最短路径(标准版)

- [P4779 【模板】单源最短路径(标准版)](【模板】单源最短路径(标准版) - 洛谷)

代码实现如下:

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
struct Edge
{
    int to;
    long long v;
    int next;
} edge[200001];
int book[100001],head[100001],cnt;
long long dis[100001];
int n,m,s;
struct Node
{
    int index;
    long long dist;
    bool operator < (const Node &x)const
     {
        return dist>x.dist;
    }
};
priority_queue<Node> q;
// 链式前向星
void add(int a,int b,long long c)
{
    cnt++;//下标
    edge[cnt].to=b;
    edge[cnt].v=c;
    edge[cnt].next=head[a];
    head[a]=cnt;
}
void dij()
{
    q.push({s,0});
    while(!q.empty())
    {
       Node x=q.top();
       q.pop();
       int u=x.index;
       if(book[u])continue;
       book[u]=1;
       for (int i = head[u]; i!=-1; i = edge[i].next)
       {
            int a = u, b = edge[i].to, v = edge[i].v;
            if (dis[b] > dis[a] + v)
            {
                dis[b] = dis[a] + v;
                q.push({b, dis[b]});
            }
       }

    }
}
int main()
{
    scanf("%d%d%d",&n,&m,&s);
    for(int i=1; i<=n; i++)
    {
        head[i]=-1;
        dis[i]=inf;
    }
    dis[s]=0;
    for(int i=1; i<=m; i++)
    {
        int a,b;
        long long c;
        scanf("%d%d%lld",&a,&b,&c);
        add(a,b,c);
    }
    dij();
    for(int i=1; i<=n; i++)
    printf("%lld ",dis[i]);
    return 0;
}
举报

相关推荐

0 条评论