hrbust 1687买房子 && hrbust 1669回家Ⅱ(二维最短路SPFA)

hrbust 1687买房子

城镇编号从1到N,小W起始城镇编号为S,小W希望在T城镇购买房子。

小W希望尽可能早的购买这个房子。请你帮他计算最少需要的时间。

当他经过一条路时,他将通过某种途径获得10金币并且消耗一定时间。
小W需要K金币。所以小W需要收集至少K金币。 

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#define MAXN 50005
#define MAXM 100100
#define INF 0x1f1f1f1f
using namespace std;
int n, m;
struct EDGE
{
    int v, next;
    int w;
}edge[MAXM*2];
int head[MAXN], e;
int vis[MAXN][650];
int d[MAXN][650];
void init()
{
    e = 0;
    memset(head, -1, sizeof(head));
}
void add(int u, int v, int w)
{
    edge[e].v = v;
    edge[e].w = w;
    edge[e].next = head[u];
    head[u] = e++;
}
struct NODE{
    int u,num;
}st,t,tt;
int bfs(int src,int end,int k)
{
    for(int i = 1; i <= n; i++) {
        for(int j=0;j<=k;j++){
        vis[i][j] = 0, d[i][j] = INF;
        }
    }
    queue<struct NODE>q;
    while(!q.empty())q.pop();
    st.u=src;
    st.num=0;
    q.push(st);
    vis[src][0] = 1;
    d[src][0] = 0;
    while( !q.empty() )
    {
        t = q.front();
        q.pop();
        vis[ t.u ][t.num]=0;
        for(int i = head[t.u]; i != -1; i = edge[i].next)
        {
            tt.num=t.num+10;tt.u=edge[i].v;
            if(tt.num>k)tt.num=k;
            int v = edge[i].v;
            int w = edge[i].w;
            if(d[t.u][t.num] + w < d[v][tt.num])
            {
                d[v][tt.num] = d[t.u][t.num] + w;
                if(!vis[v][tt.num])
                {
                    q.push(tt);
                    vis[v][tt.num] = 1;
                }
            }
        }
    }
    if(d[end][k]<INF)return d[end][k];
    else return -1;
}
int main(){
    int T,S,t,k,a,b,c;
    scanf("%d",&T);
    while(T--){
        init();
        scanf("%d%d",&n,&m);
        while(m--){
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        scanf("%d%d%d",&S,&t,&k);
        printf("%d\n",bfs(S,t,k));
    }
    return 0;
}

hrbust 1669回家Ⅱ

当车上有x个人的时候,每单位的距离将花费x单位的时间。每座城市都住着lz的一个朋友,每次经过一个城市的时候,

就会有一个朋友坐上车和lz一起回到家中。计算出回到家最少要花多少时间。

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>
#define MAXN 210
#define MAXM 210*210
#define INF 0x1f1f1f1f
using namespace std;
int n, m;
struct EDGE
{
    int v, next;
    int w;
}edge[MAXM*2];
int head[MAXN], e;
int vis[MAXN][MAXN];
int dist[MAXN][MAXN];
int d[MAXN];
void init()
{
    e = 0;
    memset(head, -1, sizeof(head));
}
void add(int u, int v, int w)
{
    edge[e].v = v;
    edge[e].w = w;
    edge[e].next = head[u];
    head[u] = e++;
}
struct NODE{
    int u,num;
}st,t,tt;
int bfs(int src,int end)
{
    for(int i = 1; i <= n; i++) {
        for(int j=0;j<=MAXN;j++){
            vis[i][j] = 0, dist[i][j] = INF;
        }
        d[i]=INF;
    }
    queue<struct NODE>q;
    while(!q.empty())q.pop();
    st.u=src;
    st.num=0;
    q.push(st);
    vis[src][0] = 1;
    dist[src][0] = 0;
    d[src]=0;
    while( !q.empty() )
    {
        t = q.front();
        q.pop();
        vis[ t.u ][t.num]=0;
        for(int i = head[t.u]; i != -1; i = edge[i].next)
        {
            tt.num=t.num+1;tt.u=edge[i].v;
            int v = edge[i].v;
            int w = edge[i].w;
            if(dist[t.u][t.num] + w*tt.num < d[v])
            {
                dist[v][tt.num]=dist[t.u][t.num] + w*tt.num;
                d[v] = dist[t.u][t.num] + w*tt.num;
                if(!vis[v][tt.num])
                {
                    q.push(tt);
                    vis[v][tt.num] = 1;
                }
            }
        }
    }
    if(d[end]<INF)return d[end];
    else return -1;
}
int main(){
    int T,a,b,c;
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        while(m--){
            scanf("%d%d%d",&a,&b,&c);
            add(a,b,c);
            add(b,a,c);
        }
        printf("%d\n",bfs(1,n));
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值