Travel in Desert UVA - 10816
阿新 • • 發佈:2020-08-06
第一關鍵字是溫度,那完全可以在保證圖聯通的前提下找到最大的最小溫度
最小生成樹
然後把所有比最小溫度還小的邊建成一個新圖,跑最短路就行了
#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; }