Vijos1404 遭遇战 (SPFA)

题意分析

看了一下题解区的dalao都是线段树+DP,然而蒟蒻看不懂。
用最短路思想直接解决这道题。

把每个人的守卫时间转换为 a-1到 b。
由于最优解会有区间相交的情况,所以要将i 与 i-1 连接一条权值为0的边。
最后注意,题目中给了s和e,一开始我没注意,一直从0开始的,然后就凉了。

代码总览

#include<bits/stdc++.h>
using namespace std;
const int nmax = 100000+10;
typedef struct{
    int to,nxt,w;
}Edge;
Edge e[nmax<<1];
int tot = 0,n,s,ee;
int head[nmax<<1],cost[nmax];
void add(int u, int v, int w){
    e[tot].to = v;
    e[tot].nxt = head[u];
    e[tot].w = w;
    head[u] = tot++;
}
void spfa(){
    memset(cost, 0x3f3f3f3f,sizeof cost); cost[s] = 0;
    bitset<nmax> inque; inque.reset();
    queue<int> q; q.push(s);
    while(!q.empty()){
        int u = q.front(); q.pop(); inque.reset(u);
        for(int i = head[u];i!=-1;i=e[i].nxt){
            int v = e[i].to, w = e[i].w;
            if(cost[v] > cost[u] + w){
                cost[v] = cost[u] + w;
                if(!inque.test(v)){
                    q.push(v);
                    inque.set(v);
                }
            }
        }
    }
}
int main(){
    scanf("%d %d %d",&n,&s,&ee);
    memset(head,-1,sizeof head);
    int u,v,w;
    for(int i = 0;i<n;++i){
        scanf("%d %d %d",&u,&v,&w);
        add((u-1)<=s?s:(u-1),v<=ee?v:ee,w);
    }
    for(int i = 1;i<=ee;++i) add(i,i-1,0);
    spfa();
    printf("%d\n",cost[ee] == 0x3f3f3f3f?-1:cost[ee]);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/pengwill97/article/details/79966200