标签:ref flag careful time connect printf ace erp mount
---恢复内容开始---
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2962
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11428 Accepted Submission(s): 1104
思路:这题既要控制最短路,也要控制height值的最大,总思路就是二分+最短路。
二分控制最大的height,最短路控制最小的路径。 值得一提的是这题格式很严格,写不对就是wa...不会PE, 还有时限卡的很紧,能优化的最好都优化了
具体看代码
#include<iostream> #include<string.h> #include<map> #include<cstdio> #include<cstring> #include<stdio.h> #include<cmath> #include<ctype.h> #include<math.h> #include<algorithm> #include<set> #include<queue> typedef long long ll; using namespace std; const ll mod=1e9+7; const int maxn=1e3+10; const int maxk=5e3+10; const int maxx=1e4+10; const ll maxe=1000+10; #define INF 0x3f3f3f3f3f3f #define Lson l,mid,rt<<1 #define Rson mid+1,r,rt<<1|1 int d[maxn];//用来存储起点到该点的最短距离,初始化为足够大 int height[maxn][maxn],le[maxn][maxn];//两点间的height,length int C,R,S,E,limit,max_he,min_le,he;// bool vis[maxn];//是否访问过,初始化false void init() { //memset(height,-1,sizeof(height)); for(int i=1;i<=C;i++) { for(int j=1;j<=i;j++) { le[i][j]=le[j][i]=mod; height[i][j]=-1; } } } bool solve(int mid) { memset(vis,false,sizeof(vis)); for(int i=1;i<=C;i++) { if(height[S][i]>=mid) d[i]=le[S][i]; else d[i]=mod; //d[i]=mod; //vis[i]=false; } //d[S]=0; //he=mod; while(true) { int flag=-1; for(int i=1;i<=C;i++) { if(!vis[i]&&d[i]!=mod&&(flag==-1||d[i]<d[flag]))//没有访问过并且距离不等于mod,因为等于mod代表当前不能走 flag=i; } if(flag==-1) break; if(flag==E) return d[flag]!=mod;//这里也是一步优化,只要走到了结束点就行了 vis[flag]=true; for(int i=1;i<=C;i++) { //if(le[i][flag]>mid) continue; if(height[i][flag]<mid) continue; d[i]=min(d[i],d[flag]+le[flag][i]); //he=min(he,height[i][flag]); //d[i]=min(d[i],d[flag]+le[flag][i]); } } return d[E]!=mod; } int main() { int ca=1; //while(cin>>C>>R) while(scanf("%d%d",&C,&R)!=EOF) { if(C==0&&R==0) break; if(ca!=1) printf("\n");//这个好像一定要放在break的后面,反正我放在前面wa了 init(); int a,b,c,e; for(int i=0;i<R;i++) { scanf("%d%d%d%d",&a,&b,&c,&e); //cin>>a>>b>>c>>e; if(c==-1) c=mod;//c=-1的话,初始化为无穷大 height[a][b]=c; height[b][a]=c; le[a][b]=e; le[b][a]=e; } //cin>>S>>E>>limit; scanf("%d%d%d",&S,&E,&limit); int l=0,r=limit; min_le=0,max_he=0; while(l<=r)//从0~imit开始二分 { int mid=(l+r)/2; if(solve(mid))//mid值可以满足,寻求更大的 { max_he=mid; min_le=d[E]; l=mid+1; } else//不能满足,寻求小的 r=mid-1; } printf("Case %d:\n",ca++); if(min_le+max_he==0) printf("cannot reach destination\n"); else { printf("maximum height = %d\n",max_he); printf("length of shortest route = %d\n",min_le); } } return 0; }
标签:ref flag careful time connect printf ace erp mount
原文地址:https://www.cnblogs.com/caijiaming/p/9442330.html