PAT 1018. Public Bike Management (30) DFS求解多最短路问题

来源:互联网 发布:淘宝用户画像怎么做 编辑:程序博客网 时间:2024/05/19 22:52
#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<string.h>#include<cmath>#include<string>using namespace std;//跪在题意理解和算法选择。/*************************题意非常复杂,一旦理解错了就没法做对。这里梳理一下:1.有一个自行车管理站,为起点0。其他各点上都有一定数量的自行车。每个站点最多能有cmax辆车。2.报告一个错误站点sp。3.从管理站出发,找一条最短路径到达sp。若选择该路径,则要把经过的所有站点调整为cmax/2。如果身上自行车不够,就从管理站运来一些自行车。如果有多余,就放在身上带到下一站。当达到终点sp后,需要把多余的带回来。4.要求先满足路径最短再满足  带出自行车数量最少最后满足带回自行车数量最少*************************//************************求解要点:1.当试图使用dijstra求解时,先去画图,判断是!否!满!足!贪!心!条!件!即画2条路,合并到同一节点,判断是否当前最优,则后续一定最优。这一题中,当sent数量最少时,无法保证后续sent最少因为sent的值与身上back和后续节点所需有关。故需要预测后续路径,故不可使用dijksra。2.此时应该用dfs暴力求解。每当找到一个可行解,修改当前最优信息。剪枝:若当前搜索肯定比最优信息差,则返回。优化:用vector来存边,而不是用矩阵。************************//***********************笔记:dfs时,不要遗漏起点的vis=0*********************/#define M 550#define INF 0xfffffint c[M],dis[M][M];int vis[M],pre[M];int endp;int cmax;struct R{int e;int l;};vector<R> road[M];int sendmin,backmin,lmin;vector<int> ansp;void dfs(int p,int len,int send,int back){if(len > lmin)return ;else if(len==lmin){if(send > sendmin)return ;else if(send == sendmin){if(back >= backmin)return ;}}//printf("p=%d,len=%d,send=%d,back=%d\n",p,len,send,back);if(p==endp){lmin=len;sendmin=send;backmin=back;ansp.clear();int pp=p;while(pp!=-1){ansp.push_back(pp);pp=pre[pp];}return ;}int i,e,l;int flen=len,fback=back,fsend=send;for(i=0;i<road[p].size();i++){e=road[p][i].e;l=road[p][i].l;if(vis[e]==1)continue;len += l;back+=c[e]-cmax/2;if(back<0){send += (-1)*back;back=0;}vis[e]=1;pre[e]=p;dfs(e,len,send,back);vis[e]=0;send=fsend;back=fback;len=flen;}}int main(){int n,sp,m;int i,j;scanf("%d%d%d%d",&cmax,&n,&sp,&m);endp=sp;c[0]=0;for(i=1;i<=n;i++)scanf("%d",&c[i]);int len,s1,s2;;R Road;for(i=0;i<m;i++){scanf("%d%d%d",&s1,&s2,&len);Road.e=s2;Road.l=len;road[s1].push_back(Road);Road.e=s1;road[s2].push_back(Road);}pre[0]=-1;memset(vis,0,sizeof(vis));lmin=sendmin=backmin=INF;vis[0]=1;//容易遗漏起点的visdfs(0,0,0,0);printf("%d ",sendmin);for(i=ansp.size()-1;i>=0;i--){if(i!=0)printf("%d->",ansp[i]);else printf("%d ",ansp[i]);}printf("%d\n",backmin);return 0;}

原创粉丝点击