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("\n%.3lf\n",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;
}

  

posted @ 2014-07-17 16:09  acm_roll  阅读(141)  评论(0编辑  收藏  举报