hdu 1598 find the most comfortable road(并查集+暴力搜索)
find the most comfortable road
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1662 Accepted Submission(s): 683
Problem Description
XX
星有许多城市,城市之间通过一种奇怪的高速公路SARS(Super Air Roam
Structure---超级空中漫游结构)进行交流,每条SARS都对行驶在上面的Flycar限制了固定的Speed,同时XX星人对
Flycar的“舒适度”有特殊要求,即乘坐过程中最高速度与最低速度的差越小乘坐越舒服
,(理解为SARS的限速要求,flycar必须瞬间提速/降速,痛苦呀 ),
但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。
但XX星人对时间却没那么多要求。要你找出一条城市间的最舒适的路径。(SARS是双向的)。
Input
输入包括多个测试实例,每个实例包括:
第一行有2个正整数n (1<n<=200)和m (m<=1000),表示有N个城市和M条SARS。
接下来的行是三个正整数StartCity,EndCity,speed,表示从表面上看StartCity到EndCity,限速为speedSARS。speed<=1000000
然后是一个正整数Q(Q<11),表示寻路的个数。
接下来Q行每行有2个正整数Start,End, 表示寻路的起终点。
第一行有2个正整数n (1<n<=200)和m (m<=1000),表示有N个城市和M条SARS。
接下来的行是三个正整数StartCity,EndCity,speed,表示从表面上看StartCity到EndCity,限速为speedSARS。speed<=1000000
然后是一个正整数Q(Q<11),表示寻路的个数。
接下来Q行每行有2个正整数Start,End, 表示寻路的起终点。
Output
每个寻路要求打印一行,仅输出一个非负整数表示最佳路线的舒适度最高速与最低速的差。如果起点和终点不能到达,那么输出-1。
Sample Input
4 4
1 2 2
2 3 4
1 4 1
3 4 2
2
1 3
1 2
Sample Output
1
0
分析:
(1)刚开始看到这道题时,首先想到的是搜索,于是乎就用了深度优先搜索,这是我的深搜的代码,无奈超时了,至于是否正确无法验证了,我觉得还凑活了,可是过不去(⊙o⊙)…
深搜的代码(超时的),如果有高手用了深搜通过了,求指教啊,是否还有其他好的剪枝没想到呢????
View Code
#include <stdio.h> #include <string.h> //#define MAX_SPEED -1 //#define MIN_SPEED 1000010 int max_speed,min_speed,min; int n,m,q; int begin,end; int speed[210][210]; int mark[210]; //pos pre void dfs(int pos,int maxs,int mins) { int i; for(i = 1;i<= n;i++) { if(mark[i]==1)continue;//访问过 if(i==pos)continue;//自己 if(speed[pos][i]==-1)continue;//不可直接到 if(speed[pos][i]<mins) mins = speed[pos][i]; if(speed[pos][i]>maxs) maxs = speed[pos][i]; if(i==end) { if(maxs-mins<min) min = maxs-mins; return; } if(min==0)return;//如果已经找到最小的了,那么就返回 mark[i]=1; dfs(i,maxs,mins); mark[i]=0; } } int main() { int x,y,sd; while(scanf("%d%d",&n,&m)!=EOF) { memset(speed,-1,sizeof(speed)); memset(mark,0,sizeof(mark)); for(int i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&sd); speed[x][y]=speed[y][x]=sd; } scanf("%d",&q); while(q--) { scanf("%d%d",&begin,&end); mark[begin]=1; min = min_speed = 1000010; max_speed = -1; dfs(begin,max_speed,min_speed); if(min<1000010) printf("%d\n",min); else printf("-1\n"); } } return 0; }
(2)于是乎就上网查了这道题的解题报告,于是乎就是用并(查集+暴力搜索)这个居然过了。。。。。。。
并查集:就是将能连通的城市合并为一个集合
排序:按照路的限速从小到大排序
暴力搜索:如果在某个集合下既有起始位置,又有终止位置,同时因为排序时从小到大排序的,所以直接用最后放进去的速度减去第一个放进去的速度即可。暴力的搜索一遍找出最符合条件的。
View Code
#include <stdio.h> #include <stdlib.h> #include <algorithm> using namespace std; typedef struct { int start,end; int length; }Edge; Edge edge[1010]; int root[210]; bool cmp(Edge a,Edge b) { return a.length<b.length; } int find_root(int a) { if(a==root[a])return a; return root[a] = find_root(root[a]); } int main() { int n,m,q; int begin,end; int min; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=0;i<m;i++) scanf("%d%d%d",&edge[i].start,&edge[i].end,&edge[i].length); sort(edge,edge+m,cmp); scanf("%d",&q); while(q--) { int fx,fy; min = 1000010; scanf("%d%d",&begin,&end); for(int k=0;k<m;k++) { int i; for(i=0;i<=n;i++) root[i]=i; for(i=k;i<m;i++) { fx = find_root(edge[i].start); fy = find_root(edge[i].end); if(fx!=fy) root[fy] = fx; if(find_root(begin)==find_root(end)) break; } if(i==m)break; if(edge[i].length-edge[k].length<min) min = edge[i].length-edge[k].length; } if(min<1000010) printf("%d\n",min); else printf("-1\n"); } } return 0; }
posted on 2012-10-19 16:56 NewPanderKing 阅读(244) 评论(0) 编辑 收藏 举报