hdu2962trucking
来源:互联网 发布:旅游导航软件 编辑:程序博客网 时间:2024/06/18 09:21
这道题难在要在一定条件下求得最短路。对车载高度进行二分,求出较高车载高度的情况下的最短路。通过判断是否能形成最短路来不断调整车载高度,如果在该车载高度情况下不能形成最短路则调低车载高度,否则调高车载高度。
#include<stdio.h>#include<iostream>#include<string.h>#include<algorithm>using namespace std;const int Max=1200;const int INF=1e9;int n,m,star,endd;int d[Max],Map[Max][Max],height[Max][Max]; //Map用来存放路长,height存放路限高bool vis[Max]; //vis标记该点是否已经访问过void init(){ for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) { Map[i][j]=INF; //将任意两点间路长初始化无穷 height[i][j]=0; //路限高初始化为0 }}bool dijstra(int lim){ memset(vis,0,sizeof(vis)); //将所有点都初始化为未访问过 for(int j=1; j<=n; j++) { if(lim<=height[star][j]) //将与起点连通且该路限高大于车高的路更新 { d[j]=Map[star][j]; } else { d[j]=INF; //其余的路设为不通 } } vis[star]=1; //标记经过该点 for(int k=0; k<n; k++) //循环n次 { int x=0,mm=INF; //将x设为不可能更新到的值,用来判断是否有与起点连通的路 for(int i=1; i<=n; i++) { //不可以是<=mm,如果有等号,则如果没有与源点的通路,就会一直更新到n,影响判断x,如果终点为n,则会一直逼近车载限高 if(!vis[i]&&d[i]<mm) //找出未访问过的点到源点最小的节点x { mm=d[x=i]; } } if(x==0) //说明起止点间没通路,需调低车载高度 return false; else if(x==endd) //说明找到最短路,需调高车载高度 return true; vis[x]=1; for(int i=1; i<=n; i++) { if(!vis[i]&&height[x][i]>=lim) //如果x到未访问的点之间路的限高大于车载高度 { d[i]=min(d[i],d[x]+Map[x][i]); //更新源点到未访问的点的路径长度 } } }}int main(){ int t=0; while(scanf("%d%d",&n,&m)!=EOF&&(n+m)!=0) { init(); int aa,bb,cc,dd; for(int i=1; i<=m; i++) { scanf("%d%d%d%d",&aa,&bb,&cc,&dd); if(cc==-1) cc=INF; Map[aa][bb]=Map[bb][aa]=dd; //双边处理 height[aa][bb]=height[bb][aa]=cc; } int limit,mid,left,right,ans; scanf("%d%d%d",&star,&endd,&limit); //起点终点和车载的限高 left=1,right=limit,ans=INF; while(left<=right) //跳出循环时的right即为最优车载高度 { mid=(left+right)/2; //对车载高度二分,求出能达到最高车载高度 if(dijstra(mid)) //如果返回true,说明有起止点间的最短路 { left=mid+1; //提高车载高度 ans=d[endd]; //记录路径长度 } else { right=mid-1; //降低车载高度 } } if(t) printf("\n"); printf("Case %d:\n",++t); if(ans==INF) //ans值最终没变说明起止点不通 printf("cannot reach destination\n"); else { printf("maximum height = %d\n",right); printf("length of shortest route = %d\n",ans); } } return 0;}
下面这个是用SPFA做的跟dijkstra的处理方法基本类似。
#include<stdio.h>#include<iostream>#include<queue>#include<string.h>#include<algorithm>using namespace std;const int MAX=999999999;const int edge_max=21000; //边的最大值const int point_max=1110; //点的最大值struct node{ int en; int height; int lenth; int next;} edge[edge_max];int pos_in_edge[point_max]; //在边中的位置int dis[point_max],n,m,Star,End,limit;bool vis[point_max];queue<int>Q;void init(){ memset(pos_in_edge,-1,sizeof(pos_in_edge)); //初始化表头 int positn=1,sta,enb,lenc,heid; for(int i=0; i<m; i++) { cin>>sta>>enb>>heid>>lenc; if(heid==-1) heid=MAX; edge[positn].en=enb; edge[positn].lenth=lenc; edge[positn].height=heid; edge[positn].next=pos_in_edge[sta]; pos_in_edge[sta]=positn++; swap(sta,enb); //做双边处理 edge[positn].en=enb; edge[positn].lenth=lenc; edge[positn].height=heid; edge[positn].next=pos_in_edge[sta]; pos_in_edge[sta]=positn++; } cin>>Star>>End>>limit;}void SPFA(int lim){ memset(vis,0,sizeof(vis)); fill(dis,dis+point_max,MAX); //dis数组初始化为最大 dis[Star]=0; //处理源点 vis[Star]=true; Q.push(Star); while(!Q.empty()) { int e_st_p=Q.front(); //边的起点 vis[e_st_p]=false; Q.pop(); for(int j=pos_in_edge[e_st_p]; j!=-1; j=edge[j].next) { if(edge[j].height<lim) continue; int e_en_p=edge[j].en; //边的终点 if(dis[e_en_p]>edge[j].lenth+dis[e_st_p]) //松弛操作 { dis[e_en_p]=edge[j].lenth+dis[e_st_p]; if(!vis[e_en_p]) { Q.push(e_en_p); vis[e_en_p]=true; } } } }}int main(){ int t=0; while(scanf("%d%d",&n,&m)!=EOF&&(n+m)!=0) { init(); int left=1,right=limit,ans=MAX,mid; while(left<=right) { mid=(left+right)/2; SPFA(mid); if(dis[End]!=MAX) { left=mid+1; ans=dis[End]; } else { right=mid-1; } } if(t) printf("\n"); printf("Case %d:\n",++t); if(ans==MAX) printf("cannot reach destination\n"); else { printf("maximum height = %d\n",right); printf("length of shortest route = %d\n",ans); } } return 0;}
0 0
- hdu2962trucking
- hdu2962Trucking 二分+最短路
- Yii girdview 時間戳做查詢時
- 算法:有三个数只出现一次,其它数出现两次
- JQuery的AJAX实现文件下载的小例子
- QT实现不规则窗体和透明窗体
- 拼图算法,将零碎小图,整理到一张大图之上,自动合并。二叉树实现
- hdu2962trucking
- 基金申请结合案例分析
- 2014年大数据行业最顶尖的人才有哪些?《财富》精选20位明星
- python操作redis简单例子
- http 发送json到服务器,服务器处理之后返回结果
- linux开发笔记:Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(2,0)
- 简单抓包代码(链路层)
- HTML5边玩边学(4):变幻的色彩
- log4j配置详解