zoukankan      html  css  js  c++  java
  • Zoj 3088 Easter Holidays SPFA+枚举

    其实就是枚举最高点和起点,然后以最高点为源点在两张图上分别做spfa。一遍最短路,一遍最长路。

    暴露出来的问题:思维不够清晰,代码能力还不够

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <string>
    #include <iostream>
    #include <map>
    #include <cstdlib>
    #include <list>
    #include <set>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    const int maxn = 1005;
    const int INF = INT_MAX / 2;
    int d[maxn],n,m,k,ansa,ansb,d1[maxn];
    int pre[maxn],pre1[maxn];
    double ansval;
    bool vis[maxn];
    
    struct Edge {
        int u,v,w;
        Edge(int u,int v,int w):u(u),v(v),w(w) {}
    };
    
    vector<Edge> ed[maxn],eup[maxn];
    
    void spfa(vector<Edge> e[],int *d,int *pre,int str,char mod) {
        memset(vis,0,sizeof(vis));
        if(mod == 's') for(int i = 1;i <= n;i++) d[i] = INF;
        else for(int i = 1;i <= n;i++) d[i] = -INF;
        d[str] = 0;
        pre[str] = 0;
        queue<int> q;
        q.push(str);
        vis[str] = true;
        while(!q.empty()) {
            int x = q.front(); q.pop();
            vis[x] = false;
            for(int i = 0;i < e[x].size();i++) {
                bool add = false;
                Edge &now = e[x][i];
                if(mod == 's') {
                    if(d[now.v] > d[x] + now.w) add = true;
                } else {
                    if(d[now.v] < d[x] + now.w) add = true;
                }
                if(add) {
                    d[now.v] = d[x] + now.w;
                    pre[now.v] = x;
                    if(vis[now.v] == false) {
                        q.push(now.v);
                        vis[now.v] = true;
                    }
                }
    
            }
        }
    }
    
    void print_up(int now) {
        if(now != ansa) putchar(' ');
        printf("%d",now);
        if(now != ansb) print_up(pre[now]);
    }
    
    void print_down(int now) {
        if(now != ansb) {
            print_down(pre1[now]);
            printf(" %d",now);
        }
    }
    
    void solve() {
        ansval = -1;
        for(int j = 1;j <= n;j++) if(eup[j].size()) {
            spfa(eup,d,pre,j,'s');
            spfa(ed,d1,pre1,j,'l');
            for(int i = 1;i <= n;i++) if(d[i] != 0 && d[i] < INF) {
                if(d1[i] != 0 && d1[i] < INF) {
                    if((double)d1[i] / d[i] > ansval) {
                        ansval = (double)d1[i] / d[i];
                        ansa = i;
                        ansb = j;
                    }
                }
            }
        }
        spfa(eup,d,pre,ansb,'s');
        spfa(ed,d1,pre1,ansb,'l');
        print_up(ansa);
        print_down(ansa);
        printf("
    %.3lf
    ",ansval);
    }
    
    int main() {
        int T; scanf("%d",&T);
        while(T--) {
            scanf("%d%d%d",&n,&m,&k);
            for(int i = 1;i <= n;i++) {
                ed[i].clear();
                eup[i].clear();
            }
            for(int i = 1;i <= m;i++) {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                ed[a].push_back(Edge(a,b,c));
            }
            for(int i = 1;i <= k;i++) {
                int a,b,c;
                scanf("%d%d%d",&a,&b,&c);
                eup[b].push_back(Edge(b,a,c));
            }
            solve();
        }
        return 0;
    }
    

      

  • 相关阅读:
    iOS 11 application 新特性
    Swift循环遍历集合方法
    Swift 使用 #warning
    swift 3.0 正则表达式查找/替换字符
    App Store 审核指南
    iOS 获取设备的各种信息的方法
    闭包(Closure)
    Swift的Guard语句
    Swift 学习指引
    Swift 4.0 废弃的柯里化
  • 原文地址:https://www.cnblogs.com/rolight/p/3851341.html
Copyright © 2011-2022 走看看