1001 舒适的路线
题目描述 Description
Z小镇是一个景色宜人的地方,吸引来自各地的观光客来此旅游观光。
Z小镇附近共有
N(1<N≤500)个景点(编 号为1,2,3,…,N),这些景点被M(0<M≤5000)条道路连接着,所有道路都是双向的,两个景点之间可能有多条道路。也许是为了保护该地 的旅游资源,Z小镇有个奇怪的规定,就是对于一条给定的公路Ri,任何在该公路上行驶的车辆速度必须为Vi。频繁的改变速度使得游客们很不舒服,因此大家 从一个景点前往另一个景点的时候,都希望选择行使过程中最大速度和最小速度的比尽可能小的路线,也就是所谓最舒适的路线。
输入描述 Input Description
第一行包含两个正整数,N和M。
接下来的M行每行包含三个正整数:x,y和v(1≤x,y≤N,0 最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速度比最小的路径。s和t不可能相同。
输出描述 Output Description
如果景点s到景点t没有路径,输出“IMPOSSIBLE”。否则输出一个数,表示最小的速度比。如果需要,输出一个既约分数。
样例输入 Sample Input
样例1
4 2
1 2 1
3 4 2
1 4
样例2
3 3
1 2 10
1 2 5
2 3 8
1 3
样例3
3 2
1 2 2
2 3 4
1 3
样例输出 Sample Output
样例1
IMPOSSIBLE
样例2
5/4
样例3
2
数据范围及提示 Data Size & Hint
N(1<N≤500)
M(0<M≤5000)
Vi在int范围内
解法
这其实是一个暴力,之所以说是并查集是用并查集来判断2个边是不是连通的。。
我写了6个版本才过的。。。。
伪代码:
先按速度排序
然后枚举for(i=1;i<=m;i++)作为第一条边(也就是最大的边)
{
for (j=i;j<=m;j++)
判断起点和终点是否在同一个并查集内(是否相连)如果是则进行最优解比较
}
反省
1.一定要调用所有写了的有用的函数。。冒泡忘记调用了跪了
2.不需要单独处理最大边(i那条边)而将j从i+1开始处理,可以直接用j从i开始处理
3.并查集只要判断2个点是否相连即可,也就是说只要祖宗相同就好,不需要管father是谁,所以只需要father[find(a)]=find(b);将ab相连
代码
#include<iostream> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> using namespace std; //头文件 struct ku { int from,to,velocity; }; struct ku a[5005]; //结构体定义 #define INF 0x7fffffff //maxlongint定义 int father[505]; int use[505]; int s,t,m,n,ecu1,ecu2; //变量定义 //-------------------------------------------------------------- int gcd(int x1,int x2) //辗转相除法子程序 { if (x2!=0) {return gcd(x2,x1%x2);} else {return x1;} } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void Euclidean() //辗转相除 { int tmp; if (ecu1<ecu2) {tmp=ecu1;ecu1=ecu2;ecu2=tmp;} int t=gcd(ecu1,ecu2); ecu1=ecu1/t; ecu2=ecu2/t; } //-------------------------------------------------------------- void bubble() //冒泡排序 { int i,j,tmp; for (i=1;i<=m-1;i++) { for (j=i+1;j<=m;j++) { if (a[i].velocity<a[j].velocity) {tmp=a[i].velocity;a[i].velocity=a[j].velocity;a[j].velocity=tmp; tmp=a[i].from;a[i].from=a[j].from;a[j].from=tmp; tmp=a[i].to;a[i].to=a[j].to;a[j].to=tmp;} } } } //-------------------------------------------------------------- int find(int x){return x==father[x]?x:father[x]=find(father[x]);} //找祖宗,路径压缩 //-------------------------------------------------------------- int main() { int i,j,anshave,k; double best; cin>>n>>m; for (int i=1;i<=m;i++) {cin>>a[i].from>>a[i].to>>a[i].velocity;} bubble(); cin>>s>>t;//读入 //cout<<"+++++++++++++++++"<<endl; for (i=1;i<=m;i++) cout<<a[i].from<<' '<<a[i].to<<' '<<a[i].velocity<<endl; //cout<<"+++++++++++++++++"<<endl; //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - anshave=0;//判断是否有解 best=INF; //最优解 for (i=1;i<=m;i++) //枚举第一条线段 { for (k=1;k<=n;k++) father[k]=k; //清空父亲 for (j=i;j<=m;j++) //插入线段(第一条无需特殊处理) { father[find(a[j].from)]=find(a[j].to); if (find(s)==find(t)) //判断是否得到解 { int p1=a[i].velocity;int p2=a[j].velocity; if (p1<p2){ int tmp=p1;p1=p2;p2=tmp;} if ((double(p1)/double(p2))<best) //判断是否得到更优解 { best=(double(p1)/double(p2)); ecu1=p1;ecu2=p2; } anshave=1; } } } //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if (anshave==1) //有解时的输出 { Euclidean(); if (ecu1==0) {cout<<'0'<<endl;return 0;} if (ecu2==1) {cout<<ecu1<<endl;return 0;} if (ecu1==ecu2) {cout<<'1'<<endl;return 0;} cout<<ecu1<<'/'<<ecu2<<endl; } else //无解时的输出 { cout<<"IMPOSSIBLE"; } return 0; }
评测结果
题目用户 | 运行结果 | 得分 | 详情 | 总耗时 | 内存占用 | 语言 | 代码 | 提交时间 |
---|---|---|---|---|---|---|---|---|
1001 舒适的路线 seekdreamer | 测试通过 Accepted |
100
|
» | 1151ms | 1736kb | C++ | 1832B | 2014/06/22 19:48:55 |
凤巢(Xeon 2.26GHz 1.5G)
|
模板
1.并查集搜索祖宗+路径压缩:int find(int x){return x==father[x]?x:father[x]=find(father[x]);}
2.求最大公因数:(1)int gcd(int a,int b) { if (b!=0) {return gcd(b,a%b);} else {return a;} }
(2)while (b!=0) {int tmp=a;a=b;b=tmp%a;} ans=a;
3.约分:(约分+输出)(暂时只支持正数)
gcd=ta与tb的最大公因数 ta/=gcd;tb/=gcd; if (ta==0) {cout<<'0'<<endl;return 0;} if (tb==1) {cout<<ta<<endl;return 0;} if (ta==tb) {cout<<'1'<<endl;return 0;} cout<<ta<<'/'<<tb<<endl;
鸣谢与数据
鸣谢给我数据的吴桐。。最后上三组样例数据(不是wikioi评测的数据。。是我自己做的)
test1:http://www.cnblogs.com/seekdreamer/articles/3803071.html
test2:http://www.cnblogs.com/seekdreamer/articles/3803076.html
test3:test3.in
2 1
2 1 6
1 2
test3.out :1