Travel in Desert UVA - 10816

Miku

第一关键字是温度,那完全可以在保证图联通的前提下找到最大的最小温度

最小生成树

然后把所有比最小温度还小的边建成一个新图,跑最短路就行了

#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;
} 
posted @ 2020-08-06 13:31  Simex  阅读(65)  评论(0编辑  收藏  举报