HDU 4725 (加点)

本文介绍了一道Vjudge平台上的最短路径问题,并详细解释了解题思路及建图方法。通过将每一层视为两个节点,增加额外的2n个点来构建图,使用Dijkstra算法求解从1到n的最小花费。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接: Vjudge

题意 : 给 n个点 m个双向变 层之间的花费C 下一行给出每一个点所在层数 后面给U——>V的花费 求 1-n最小花费

看到第一眼就知道是dijk求,但是不会建图(还读错题一次),练习赛的时候大佬都做出来了…. 自己还是太菜了

建图方法 把每一层看成两个点,多建 2*n个点,然后新建点到自己层点的距离为0 到下一层新建的点为 c 然后自己最短路跑就行了 (为什么不是每层多建一个点而是两个呢? 这是因为最短路的缘故 如果 1层的两个点互不相连 这需要跑到上一层再跑回来 但再用dijk时无法回来(跟新点时那个点已经被标记))

代码 :


#include <bits/stdc++.h>
using namespace std;
const long long mod=1e9+7;
#define ll long long
#define inf 0x3f3f3f3f
void intt()
{freopen("in","r",stdin);}

struct node
{
    int v;
    int cost;
    node(){}
    node(int x,int y):v(x),cost(y){}
    bool friend operator <(const node &a,const node &b)
    {
        return a.cost>b.cost;
    }
};
vector<node>qq[300007];

int n,m,c;
void dijk()
{
    int vis[300007];
    int dis[300007];
    memset(vis,0,sizeof(vis));
    memset(dis,inf,sizeof(dis));
    dis[1]=0;
    priority_queue<node>q;
    q.push(node(1,0));
    while(!q.empty())
    {

            node t=q.top();
            q.pop();
            if(vis[t.v]) continue;
            vis[t.v]=1;
            for(int i=0;i<qq[t.v].size();i++)
            {       int v=qq[t.v][i].v;
                  if(!vis[v]&&dis[v]>dis[t.v]+qq[t.v][i].cost)
                  {
                        dis[v]=dis[t.v]+qq[t.v][i].cost;
                        q.push(node(v,dis[v]));

                  }

            }




    }
    if(dis[n]==inf) printf("-1\n");
    else
   printf("%d\n",dis[n]);
}
int main()
{

   //intt();
    int t;
    int tt=1;
    scanf("%d",&t);
    while(t--)
    {
        for(int i=0;i<=3*n;i++) qq[i].clear();
        scanf("%d%d%d",&n,&m,&c);
        int maxx=0;
        for(int i=1;i<=n;i++)
        {
            int k;
            scanf("%d",&k);
            qq[n+k*2].push_back(node(i,0));
            qq[i].push_back(node(n+k*2-1,0));

        }
       for(int i=n+2;i<3*n;i+=2)
        {
            qq[i+1].push_back(node(i,c));
            qq[i-1].push_back(node(i+2,c));
        }


        for(int i=0;i<m;i++)
        {
            int u,v,val;
            scanf("%d%d%d",&u,&v,&val);
            qq[u].push_back(node(v,val));
            qq[v].push_back(node(u,val));

        }
        printf("Case #%d: ",tt++);
        dijk();

    }


    return 0;
}

努力!!加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值