几道最短路裸题--解法dij

讲座里讲了好多最短路的算法,没来得及思考和应用因为目前碰到的水题,dij就完全可以解决了,目前的目标是昨天听到的dij的二叉堆优化,研究成功会第一时间放到这里。

还有spfa可以解决负权的问题,由于学长是曾经研究过刘汝佳的算法入门经典的,他十分注重一个模型,DAG。


第一道hdu1548

A strange lift


#include<iostream>
#include<cstdio>
#include<cstring>
#define max_n 300
#define maxn 99999
using namespace std;
int dist[max_n],map[max_n][max_n];
int vis[max_n],n;
void dijk(int v)
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
        dist[i]=map[v][i];
    dist[v]=0;
    vis[v]=1;
    for(i=1;i<=n;i++)
    {
        int m=maxn,f=0;
        for(int j=1;j<=n;j++)
            if(!vis[j]&&m>dist[j])
            {
                m=dist[j];
                f=j;
            }
        if(f==0)
            break;
        vis[f]=1;
        for(j=1;j<=n;j++)
            if(!vis[j] && dist[j]>dist[f]+map[f][j])
                dist[j]=dist[f]+map[f][j];
    }
}
int button[max_n];
int main()
{
    int a,b,i,j;
    while(scanf("%d%d%d",&n,&a,&b)!=EOF && n)
    {
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                map[i][j]=maxn;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&button[i]);
            if(i+button[i]<=n)
                map[i][button[i]+i]=1;
            if(i-button[i]>=1)
                map[i][i-button[i]]=1;
        }
        dijk(a);
        if(dist[b]==maxn)
            printf("-1\n");
        else
            printf("%d\n",dist[b]);
    }
    return 0;
}
        


第二道hdu 3790

最短路径问题

#include<stdio.h>
#include<string.h>
#define max_n 1010
#define maxn 99999
struct node
{
    int l,p;
};    
node dist[max_n],map[max_n][max_n];
int vis[max_n],n;
void dijk(int v)
{
    int i,j;
    memset(vis,0,sizeof(vis));
    for(i=1;i<=n;i++)
    {
        dist[i].l=map[v][i].l;
        dist[i].p=map[v][i].p;
        //dist[i].l=maxn;
        //dist[i].p=maxn;
    }
    dist[v].l=0;
    dist[v].p=0;
    vis[v]=1;
    for(i=1;i<=n;i++)
    {
        int m=maxn,f=0;
        for(j=1;j<=n;j++)
            if(!vis[j] && m>dist[j].l)
            {
                m=dist[j].l;
                f=j;
            }
        if(f==0)
            break;
        vis[f]=1;

        for(j=1;j<=n;j++)
        {
            if(!vis[j] && dist[j].l>dist[f].l+map[f][j].l)
            {
                dist[j].l=dist[f].l+map[f][j].l;
                dist[j].p=dist[f].p+map[f][j].p;
            }
            if(!vis[j] && dist[j].l==dist[f].l+map[f][j].l &&dist[j].p>dist[f].p+map[f][j].p)
                dist[j].p=dist[f].p+map[f][j].p;
        }
    }
}
int main()
{
    int a,b,i,j,m,s,t,c,d;
    while(scanf("%d%d",&n,&m)!=EOF &&n &&m)
    {
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
            {
                map[i][j].l=maxn;
                map[i][j].p=maxn;
            }
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d%d",&a,&b,&c,&d);
            if(map[a][b].l>c)
            {
                map[a][b].l=map[b][a].l=c;
                map[a][b].p=map[b][a].p=d;
            }
            if(map[a][b].l==c && map[a][b].p>d)
            {
                map[a][b].p=map[b][a].p=d;
            }
        }
        scanf("%d%d",&s,&t);
        dijk(s);
        int ans=dist[t].l;
        int ans1=dist[t].p;
        printf("%d %d\n",ans,ans1);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值