Travel in Desert UVA - 10816
第一关键字是温度,那完全可以在保证图联通的前提下找到最大的最小温度
最小生成树
然后把所有比最小温度还小的边建成一个新图,跑最短路就行了
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<cstring>
#include<stack>
using namespace std;
int s,t;
int n,e;
int x,y;
double r,d;
int fa[201];
double dis[201];
int head[201];
int b=1;
int lu[201];
double ht[201];
double maxn;
bool vis[201];
struct dj{
double v;
int id;
friend bool operator < (dj xxx,dj yyy){
return xxx.v>yyy.v;
}
};
dj too,tooo;
priority_queue <dj> q;
struct ee{
int to;
int ne;
int f;
double t;
double l;
}e1[20001],e2[20001];
int p;
void add(int f,int to,double t,double l){
p++;
e1[p].ne=head[f];
e1[p].to=to;
e1[p].f=f;
e1[p].t=t;
e1[p].l=l;
head[f]=p;
}
void add2(int f,int to,double t,double l){
p++;
e2[p].f=f;
e2[p].ne=head[f];
e2[p].to=to;
e2[p].t=t;
e2[p].l=l;
head[f]=p;
}
bool cmp (ee xx,ee yy){
return xx.t<yy.t;
}
int find(int x){
return fa[x]==x? x: fa[x]=find(fa[x]);
}
void sp(){
for(int i=1;i<=n;++i){
dis[i]=0x3f3f3f3f;
}
dis[s]=0;
lu[s]=s;
too.id=s;
too.v=0;
q.push(too);
while(!q.empty()){
too=q.top();
q.pop();
if(vis[too.id]) continue;
vis[too.id]=1;
for(int i=head[too.id];i;i=e2[i].ne){
if(dis[e2[i].to]>dis[too.id]+e2[i].l){
dis[e2[i].to]=dis[too.id]+e2[i].l;
lu[e2[i].to]=too.id;
ht[e2[i].to]=max(ht[too.id],e2[i].t);
tooo.id=e2[i].to;//这么干是对的
tooo.v=dis[e2[i].to];
if(!vis[e2[i].to])
q.push(tooo);
}
}
}
return ;
}
void kr(){
b=1;
p=0;
for(int i=1;i<=n;++i)
fa[i]=i;
sort(e1+1,e1+e+1,cmp);
memset(head,0,sizeof(head));
for( int i=1;i<=e;i++){
x=find(e1[i].f);
y=find(e1[i].to);
if(x!=y){
fa[x]=y;
maxn=max(maxn,e1[i].t);
if(find(s)==find(t))
break;
}
}//先找最大温度
for(int i=1;i<=e;++i){
if(e1[i].t>maxn) break;
add2(e1[i].f,e1[i].to,e1[i].t,e1[i].l);
add2(e1[i].to,e1[i].f,e1[i].t,e1[i].l);
}//建新图
sp();
return ;
}
void pr(int now){//天然的栈,倒序输出
if(now==s){
cout<<s;
return ;
}
pr(lu[now]);
if(now!=t)
printf(" %d",now);
else{
printf(" %d",now);
}
}
int main(){
while((scanf("%d%d",&n,&e))!=EOF){//多组数据
maxn=0;
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
memset(lu,0,sizeof(lu));
memset(ht,0,sizeof(ht));
p=0;
scanf("%d%d",&s,&t);
for(int i=1;i<=e;++i){
scanf("%d%d%lf%lf",&x,&y,&r,&d);
add(x,y,r,d);
}
kr();
pr(t);
printf("\n");
printf("%.1lf %.1lf\n",dis[t],ht[t]);
}
return 0;
}