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;
}

  

Zoj 3088 Easter Holidays SPFA+枚举

时间: 2024-10-11 01:00:35

Zoj 3088 Easter Holidays SPFA+枚举的相关文章

zoj 3088 Easter Holidays (spfa )

Easter Holidays Time Limit: 1 Second      Memory Limit: 32768 KB      Special Judge Scandinavians often make vacation during the Easter holidays in the largest ski resort Are. Are provides fantastic ski conditions, many ski lifts and slopes of variou

ZOJ3088 Easter Holidays spfa 最长路 最短路 路径打印

题目链接: 3088 题意:一个滑雪胜地包含了n 个地点,m 个滑雪斜坡,k 架雪橇,其中2≤n≤1000.1≤m≤1000.1≤k≤1000.滑雪斜坡和雪橇总是从一个地点到另一个地点:滑雪斜坡是从高地点到低地点,而雪橇刚好相反(注意,雪橇不能下降).Per 是一个滑雪初学者,他很害怕雪橇,尽管他想滑得尽可能快.现在,他发现他可以选择不同的雪橇和滑雪斜坡.他现在想这样安排他的滑雪行程: 1) 从一架雪橇的起点出发并最终回到起点. 2) 这个过程分为两个阶段:第一阶段,乘坐一架或多架雪橇上升:第二

ZOJ 3794 Greedy Driver spfa

题意: 给定n个点,m条有向边,邮箱容量. 起点在1,终点在n,开始邮箱满油. 下面m行表示起点终点和这条边的耗油量(就是长度) 再下面给出一个数字m表示有P个加油站,可以免费加满油. 下面一行P个数字表示加油站的点标. 再下面一个整数Q 下面Q行 u v 表示在u点有销售站,可以卖掉邮箱里的任意数量的油,每以单位v元. 问跑到终点能获得最多多少元. 先求个每个点的最大剩余油量 f[i], 再把边反向,求每个点距离终点的最短路 dis[i]. 然后枚举一下每个销售点即可,( f[i] - dis

zoj 1008 Gnome Tetravex (dfs+枚举)

Gnome Tetravex Time Limit: 10 Seconds      Memory Limit: 32768 KB Hart is engaged in playing an interesting game, Gnome Tetravex, these days. In the game, at the beginning, the player is given n*n squares. Each square is divided into four triangles m

zoj2027Travelling Fee(Spfa+枚举)

题目链接: huangjing 题意: 给了起始和终点城市,然后给了若干对城市和距离,然后从起点到终点最小的费用,但是有一个新优惠,那就是费用最大的两个城市之间可以免费. 思路: 最开始以为求了最短路然后减去最大的费用即可.但是想了一组样例就知道是错的. 比如1--->2---->3 然后有直接1----->3,那么如果按刚才的思路,那么最小费用就是2 2     5                  8 所以思路是错的..然后在cp的帮助下得知,既然不知道哪条是最大的费用路,那么我们就

ZOJ 2770 差分约束+SPFA

Burn the Linked Camp Time Limit: 2 Seconds      Memory Limit: 65536 KB It is well known that, in the period of The Three Empires, Liu Bei, the emperor of the Shu Empire, was defeated by Lu Xun, a general of the Wu Empire. The defeat was due to Liu Be

HDU - 3499 Flight 双向SPFA+枚举中间边

Flight Recently, Shua Shua had a big quarrel with his GF. He is so upset that he decides to take a trip to some other city to avoid meeting her. He will travel only by air and he can go to any city if there exists a flight and it can help him reduce

zoj 3946 Highway Project spfa

题意:一个帝国有 n 个城市,可以在城市两两之间建立 m 条高速公路,建立 x-y 之间的高速路需要时间 d,花费为 c, 最后建立完边(<=m)后使得首都 0 号城市到各个城市(1~n-1)的总时间最少,在多个时间满足条件下再选花费最少的. 思路:直接spfa,当有多个点使得时间最少时,选花费最小的边. #include <iostream> #include <algorithm> #include <string.h> #include <stdio.

hdu3986 spfa+枚举

这题让我第一次感受到了什么叫做在绝望中A题.这题我总共交了18次,TLE不知道几次,WA也不知道几次. 这题不能用dijkstra,用这个我一直超时(我没试过dij+优先队列优化,好像优先队列优化后可以过).. 用了我近一天的时间...... #include<stdio.h> #include<queue> #include<string.h> using namespace std; #define maxn 1002 #define INF 99999999 st