SPFA+DP&&http://acm.nyist.net/JudgeOnline/problem.php?pid=203

本文分享了一道将最短路径算法与0-1背包问题相结合的综合题解题经验,详细展示了使用邻接表实现的SPFA算法流程,并探讨了调试过程中遇到的问题。

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

这几天忙着复习也没顾得刷题,,罪过啊,,O(∩_∩)O~

这一题是一道小综合题,最短路和0—1背包结合,,调试了好大一会,,纠结,,感觉自己弱爆了,,

#include<iostream> #include<algorithm> #include<cstdio> #include<string.h> #define N 101 #define M 0x3f #include<queue> using namespace std; typedef struct { int to,len,next; }Node; Node node[1000*N]; int dist[N],head[N],cost[N],result[10000*N]; bool visit[N]; int num,s,n,m; void init() { num=0; memset(head,-1,sizeof(head)); memset(result,0,sizeof(result)); memset(dist,M,sizeof(dist));//有时候这样初始化不正确 /* 这样写保险,,,, for(int i=0;i<=n;++i) dist[i]=M;*/ } void Add(int a,int b,int c) { node[num].len=c; node[num].to= b; node[num].next=head[a]; head[a]=num++; } void SPFA() { dist[0]=0; memset(visit,false,sizeof(visit)); queue<int> Q; Q.push(0); visit[0]=true; while(!Q.empty()) { int u=Q.front(); Q.pop(); visit[u]=false; for(int i=head[u];i!=-1;i=node[i].next) { //这一点一开始写的是 错的离谱,, /*{ if(dist[u]+node[i].len<dist[node[i].to]) dist[node[i].to]=dist[u]+node[i].len; if(!visit[node[i].to]) { Q.push(node[i].to); visit[node[i].to]=true; } } */ if(dist[u]+node[i].len<dist[node[i].to]) { dist[node[i].to]=dist[u]+node[i].len; if(!visit[node[i].to]) { Q.push(node[i].to); visit[node[i].to]=true; } } } } int main() { int Case; scanf("%d",&Case); while(Case--) { init(); scanf("%d%d%d",&s,&n,&m); for(int i=0;i!=m;++i) { int a,b,c; scanf("%d%d%d",&a,&b,&c); Add(a,b,c); Add(b,a,c); } for(int i=1;i<=n;++i) scanf("%d",&cost[i]); SPFA(); for(int i=1;i<=n;++i) for(int j=s;j>=dist[i];--j) result[j]=max(result[j-dist[i]]+cost[i],result[j]); printf("%d\n",result[s]); } //system("pause"); return 0; }

我感觉像邻接表,循环链表了,能自己写的自己写也挺好的,,毕竟容易查找错误,而且能加深对邻接表,循环链表的理解,,

#include<iostream> #include<algorithm> #include<cstdio> #include<string.h> #define N 101 #define M 0x3f using namespace std; typedef struct { int to,len,next; }Node; Node node[1000*N]; int dist[N],head[N],cost[N],result[10000*N],Q[N*1000]; bool visit[N]; int num,s,n,m; void init() { num=0; memset(head,-1,sizeof(head)); memset(result,0,sizeof(result)); memset(dist,M,sizeof(dist));//有时候这样初始化不正确 /* 这样写保险,,,, for(int i=0;i<=n;++i) dist[i]=M;*/ } void Add(int a,int b,int c) { node[num].len=c; node[num].to= b; node[num].next=head[a]; head[a]=num++; } void SPFA() { dist[0]=0; memset(visit,false,sizeof(visit)); int top=-1,tail=-1; Q[++top]=0; visit[0]=true; while(top>tail) { int u=Q[++tail]; visit[u]=false; for(int i=head[u];i!=-1;i=node[i].next) if(dist[u]+node[i].len<dist[node[i].to]) { dist[node[i].to]=dist[u]+node[i].len; if(!visit[node[i].to]) { Q[++top]=node[i].to; visit[node[i].to]=true; } } } } int main() { int Case; scanf("%d",&Case); while(Case--) { init(); scanf("%d%d%d",&s,&n,&m); for(int i=0;i!=m;++i) { int a,b,c; scanf("%d%d%d",&a,&b,&c); Add(a,b,c); Add(b,a,c); } for(int i=1;i<=n;++i) scanf("%d",&cost[i]); SPFA(); for(int i=1;i<=n;++i) for(int j=s;j>=dist[i];--j) result[j]=max(result[j-dist[i]]+cost[i],result[j]); printf("%d\n",result[s]); } //system("pause"); return 0; }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值