uva10816 Travel in Desert(MST + 最短路)

来源:互联网 发布:端口被系统占用 编辑:程序博客网 时间:2024/05/18 02:03

题意:一群人在沙漠中,给定了n个点,m条路,双向的。每条路有一定的长度且路上的温度也不一样。现在这群人想从s到t去,要使路径中的最高温度最低,有多条路径的情况下选择路程最短的,输出路径,最高温度,路程。


思路:算是一道考验代码的图论题,并不是很难。可以想到最高温度最低,就用贪心(MST)直到s,t连通和保留温度t相同的边。
然后在这些边上做最短路并保存路径打印出来。

/*****************************************Author      :Crazy_AC(JamesQi)Time        :2016File Name   :*****************************************/// #pragma comment(linker, "/STACK:1024000000,1024000000")#include <iostream>#include <algorithm>#include <iomanip>#include <sstream>#include <string>#include <stack>#include <queue>#include <deque>#include <vector>#include <map>#include <set>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <climits>using namespace std;#define MEM(x,y) memset(x, y,sizeof x)#define pk push_back#define lson rt << 1#define rson rt << 1 | 1#define bug cout << "BUG HERE\n"typedef long long LL;typedef unsigned long long ULL;typedef pair<int,double> ii;typedef pair<ii,int> iii;const double eps = 1e-8;const double pi = 4 * atan(1);const int inf = 1 << 30;const int INF = 0x3f3f3f3f;const int MOD = 1e9 + 7;int nCase = 0;int dcmp(double x){//精度正负、0的判断    if (fabs(x) < eps) return 0;    return x < 0?-1:1;}inline int read(){    char c = getchar();    while (!isdigit(c)) c = getchar();    int x = 0;    while (isdigit(c)) {        x = x * 10 + c - '0';        c = getchar();    }    return x;}const int maxn = 123;const int maxm = 12345;struct Edge {    int u, v;    double t, d;    void read() {        scanf("%d %d %lf %lf", &u, &v, &t, &d);    }    bool operator < (const Edge& rhs) const {        return t < rhs.t || (t == rhs.t && d < rhs.d);    }}edges[maxm];struct state {    int u;    double d;    state(int u,double d) {        this->u = u;        this->d = d;    }     bool operator < (const state& rhs) const {        return d > rhs.d;    }};int n, m;int S, T;vector<ii> G[maxn];vector<int> ans;int f[maxn];int find(int x) {    return f[x] == x ? x : f[x] = find(f[x]);}void input() {    scanf("%d %d", &S, &T);    for (int i = 1;i <= n;++i)        G[i].clear(), f[i] = i;    for (int i = 0;i < m;++i)        edges[i].read();    sort(edges, edges + m);}double dis[maxn];int vis[maxn];int p[maxn];void put(int u) {    if (u == 0) return ;    put(p[u]);    ans.push_back(u);    return ;}double dijk() {    priority_queue<state> que;    for (int i = 0;i <= n;++i)        dis[i] = inf;    memset(vis, 0,sizeof vis);    dis[S] = p[S] = 0;    que.push(state(S, dis[S]));    while(!que.empty()) {        int u = que.top().u;        que.pop();        if (vis[u]) continue;        vis[u] = 1;        for (int i = 0;i < G[u].size();++i) {            int v = G[u][i].first;            double d = G[u][i].second;            if (dis[v] > dis[u] + d) {                dis[v] = dis[u] + d;                p[v] = u;                que.push(state(v, dis[v]));            }        }    }    ans.clear();    put(T);    for (int i = 0;i < ans.size();++i)         printf("%d%c", ans[i], i == ans.size() - 1?'\n':' ');    return dis[T];}void solve() {    bool ok = false;    double temp;    for (int i = 0;i < m;++i) {        if (ok && edges[i].t - edges[i-1].t > eps) break;        int u = edges[i].u;        int v = edges[i].v;        int t1 = find(u);        int t2 = find(v);        G[u].push_back(ii(v, edges[i].d));        G[v].push_back(ii(u, edges[i].d));        if (t1 != t2)            f[t1] = t2;        if (find(S) == find(T)) {            ok = true;            temp = edges[i].t;        }    }    double o = dijk();    printf("%.1lf %.1lf\n", o, temp);}int main(int argc, const char * argv[]){       // freopen("in.txt","r",stdin);    // freopen("out.txt","w",stdout);    while(scanf("%d %d", &n, &m) != EOF) {        input();        solve();    }    return 0;}
0 0
原创粉丝点击