UVA-10816 - Travel in Desert(dijkstra)

题意:有N个点,E条边,起点S,终点T,每条边都有一个距离值D,和温度值R,问你从S到T的最大温度值最小的情况下距离最短.

分析:二分温度值,然后dijkstra求S到T的最短距离

// File Name: 10816.cpp
// Author: zlbing
// Created Time: 2013/2/18 0:27:01

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define MAXN 205
struct Edge{
    int u,v;
    double R,D;
};
vector<int>G[MAXN];
vector<Edge> edges;
double d[MAXN];
struct node{
    int u;
    double cost;
    bool operator <(const node& a)const{
        return cost>a.cost;
    }
};
int p[MAXN];
int S,T;
int N,E;
double ans;
const double eps=1e-8;
bool dijkstra(double mid)
{
    priority_queue<node> Q;
    node t,tt;
    for(int i=0;i<=N;i++)
        d[i]=-1;
    CL(p,-1);
    t.u=S;
    t.cost=0;
    Q.push(t);
    d[S]=0;
    while(!Q.empty())
    {
        t=Q.top();
        Q.pop();
        if(t.u==T){
            ans=t.cost;
            return true;
        }
        for(int i=0;i<G[t.u].size();i++)
        {
            Edge e=edges[G[t.u][i]];
            //printf("e.u--%d  e.v---%d  e.cost--%lf\n",e.u,e.v,e.D);
            //printf("e.R---%lf  mid--%lf\n",e.R,mid);
            if(e.R<=mid){
                //printf("aaaaaaaaaaa\n");
                if(d[e.v]<0||d[e.v]>t.cost+e.D+eps)
                {
                    tt.u=e.v;
                    tt.cost=t.cost+e.D;
                    d[tt.u]=tt.cost;
                    p[e.v]=e.u;
                //printf("t.u--%d  t.cost--%lf\n",tt.u,tt.cost);
                    Q.push(tt);
                }
            }
        }
    }
    return false;
}
void print(int s,int u)
{
    if(s==u){
        printf("%d",s);
        return;
    }
    print(s,p[u]);
    printf(" %d",u);
}
int main(){
    //freopen("out.txt","w",stdout);
    while(~scanf("%d%d",&N,&E))
    {
        scanf("%d%d",&S,&T);
        int a,b;
        double R,D;
        double maxn=0,minn=INF;
        for(int i=0;i<=N;i++)G[i].clear();
        edges.clear();
        for(int i=0;i<E;i++)
        {
            scanf("%d%d%lf%lf",&a,&b,&R,&D);
            edges.push_back((Edge){a,b,R,D});
            edges.push_back((Edge){b,a,R,D});
            int m=edges.size();
            G[a].push_back(m-2);
            G[b].push_back(m-1);
            maxn=max(maxn,R);
            minn=min(minn,R);
        }
        double Left=minn,Right=maxn;
        while(Right-Left>eps)
        {
            double mid=(Left+Right)/2;
            //printf("Right---%lf Left=---%lf  mid---%lf\n",Right,Left,mid);
            if(dijkstra(mid))
                Right=mid;
            else Left=mid;
        }
        dijkstra(Right);
        print(S,T);
        printf("\n");
        printf("%.1lf %.1lf\n",ans,Right);
    }
    return 0;
}

 

posted @ 2013-04-19 14:15  z.arbitrary  阅读(416)  评论(0编辑  收藏  举报