关于spfa:它半死不活(违规紫衫)
查看原帖
关于spfa:它半死不活(违规紫衫)
404032
hangxinzhu楼主2024/11/25 17:53

rt,分层图spfa跑了72分,超越我们机房一众dijkstra和纯树剖:)

#include "bits/stdc++.h"

#define ll long long
#define endl "\n"
#define maxn 200005

using namespace std;

ll read(){
    ll f = 1,k = 0;
    char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-') f = -f;
        c = getchar();
    }
    while(c >= '0' && c <= '9'){
        k = (k<<1)+(k<<3)+c-48;
        c = getchar();
    }
    return f*k;
}

struct Query{
    int u,v,id;
    ll ans;
}query[maxn];

struct Edge{
    int v;
    ll w;
};

int n,q;
ll val[maxn],dis[maxn<<1],vis[maxn<<1];
vector<Edge> E[maxn<<1];

void insert(int u,int v,ll w){
    E[u].push_back(Edge{v,w});
    return;
}

void dijkstra(int x){
    for(int i = 1;i <= 2*n;i++){
        dis[i] = LONG_LONG_MAX;
        vis[i] = 0;
    }
    queue<pair<ll,int>> pq;
    dis[x] = 0;
    pq.push({0,x});
    while(!pq.empty()){
        int u = pq.front().second;pq.pop();
        vis[u] = 0;
        for(auto [v,w]:E[u]){
            if(dis[v] > dis[u]+w){
                dis[v] = dis[u]+w;
                if(!vis[v]){
                    vis[v] = 1;
                    pq.push({dis[v],v});
                } 
            }
        }
    }
}

bool cmp(Query x,Query y){
    if(x.u == y.u){
        return x.v < y.v;
    }else return x.u < y.u;
}
bool cmp2(Query x,Query y){
    return x.id < y.id;
}

int main(){
    n = read();q = read();
    for(int i = 1;i <= n;i++)   val[i] = read();
    for(int i = 1;i < n;i++){
        int u = read(),v = read();ll w = read();
        insert(u,v,w);
        insert(v,u,w);
        insert(u+n,v+n,w);
        insert(v+n,u+n,w);
        insert(u,v+n,w-val[v]);
        insert(v,u+n,w-val[u]);
    }
    for(int i = 1;i <= n;i++) insert(i,i+n,-val[i]);
    dijkstra(1);
    for(int i = 1;i <= q;i++){
        int u = read(),v = read();
        if(u > v) swap(u,v);
        query[i] = {u,v,i};
    }
    sort(query+1,query+1+q,cmp);
    for(int i = 1;i <= q;){
        int u = query[i].u;
        dijkstra(u);
        while(query[i].u == u){
            int v = query[i].v;
            query[i].ans = val[u]+val[v]-dis[v+n];
            i++;
        }
    }
    sort(query+1,query+1+q,cmp2);
    for(int i = 1;i <= q;i++){
        cout << query[i].ans << endl;
    }
    return 0;
}

2024/11/25 17:53
加载中...