反正也不提交就随便写写了orz

有原题但是没有找qwq

[题目地址](https://www.luogu.org/problemnew/show/T57559)

题面:简单来说,它要从标号为1的星球到标号为n的星球,某一些星球之间有航线。由于超时空隧道的存在,从一个星球到另一个星球时间可能会倒流,而且,从星球a到b耗费的时间和星球b到a耗费的时间不一定相同。

宇宙法规定:“禁止在出发时间前到达目的地。” 每艘飞船上都有速度调节装置,可以调节飞行的时间。其功能可以使得整次航程中所有两星球间的飞行时间增加或减少相同的整数值。你的任务是帮助它调整速度调节器,找出一条最短时间到达目的地的路径。

出题人为了考一个负环也是挺累的什么题目都编的出来,一眼看出来SPFA,果然喜欢负权边的出题人可以拯救SPFA,两眼看出来二分+SPFA,二分的值是给每一条边增加的权,有几个注意事项罢了

1. 在1到n的路径上有负环可以经过则不存在最短路

2. 1到n的最短路必须为非负数

所以考试的时候直接一梭子码完,先判断是否连通然后无脑二分SPFA就行了,判断条件是如果图内存在负环或到n点最短路为负数则lef = mid,拿到了60分

可是!

最重要的是1到n路径上可能有些点永远不会到达,而这些点上如果有负环和求1至n的最短路并没有卵子关系,而因为二分条件如此,所以开始就要记录从1到n的任意路径上所包含点的集合才可以进行SPFA,剩余的点略去

莫名其妙

代码:(3337ms)

有效率更高的代码但懒得写

```
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#define LL long long
using namespace std;
struct node{
    int x, quan;
    node (int a, int b) : x(a), quan(b){
    }
};
const int INF = 999999999;
vector <node> k[1100];
int n, m, t1, t2, t3, cnt[1100], dis[1100], lef, rig, mid, pre[1100];
bool bol[1100], vis[1100], flag, use[1100];
void solve(int i){
    use[i] = true;
    if (pre[i]) solve(pre[i]);
}
void dfs(int i){
    vis[i] = true;
    if (i == n) {
        solve(i);
        flag = true;
        return;
    }
    int p = k[i].size();
    for (int j = 0; j < p; ++j){
        if (!vis[k[i][j].x]) {
            pre[k[i][j].x] = i;
            dfs(k[i][j].x);
        }
    }
}
bool SPFA(){
    for (int i = 0; i <= n; ++i){
        dis[i] = INF;
    }
    memset(cnt, 0, sizeof(cnt));
    memset(bol, 0, sizeof(bol));
    queue <int> que;
    dis[1] = 0;
    que.push(1);
    while(!que.empty()){
        int x = que.front();
        que.pop();
        bol[x] = false;
        int p = k[x].size();
        for (int j = 0; j < p; ++j){
            node e = k[x][j];
            if (use[e.x] and dis[e.x] > dis[x]+e.quan+mid){
                dis[e.x] = dis[x]+e.quan+mid;
                if (!bol[e.x]){
                    bol[e.x] = true;
                    if (cnt[e.x]++ > n) {
                        return true;
                    }
                    que.push(e.x);
                }
            }
        }
    }
    return false;
}
int main(){
    int T;
    scanf("%d", &T);
    while(T--){
        scanf("%d %d", &n, &m);
        for (int i = 0; i <= n; ++i){
            k[i].clear();
        }
        memset(cnt, 0, sizeof(cnt));
        memset(use, 0, sizeof(use));
        memset(pre, 0, sizeof(pre));
        for (int i = 0; i < m; ++i){
            scanf("%d %d %d", &t1, &t2, &t3);
            k[t1].push_back(node(t2, t3));
        }
        memset(vis, 0, sizeof(vis));
        flag = false;
        dfs(1);
        if (!flag) {
            printf("-1\n");
        }else{
            lef = -100001;
            rig = 100001;
            while (lef+1 < rig) {
                mid = (lef+rig)/2;
                if (SPFA() or dis[n] < 0) lef = mid;
                else rig = mid;
            }
            mid = rig;
            SPFA();
            printf("%d\n", dis[n]);
        }
    }
}
```