• [vijos1844]遭遇战<SPFA>


    题目链接:https://vijos.org/p/1404

    我在二分查找区找到这道题的,没错这就是一道摆在二分区但是可以用SPFA做的一道题(当然我后来去看了下分区,貌似这题的方法很多)

    这一题还是比较有趣的,我用的是SPFA,状况还是层出不穷,我原本以为可以一次过,结果就一个点没过,好吧这才是最绝望的。。。

    后来发现只是因为-1的情况判断失误造成的。。。。

    这道题其实看上去像个区间类的dp,但其实也可以用图论做。。。

    怎么建图呢,我们建图是个有向图,我们把士兵守卫的区段的起始时间和终止时间+1连边。。。。

    好吧我们来说一说为啥是和终止时间+1连边。。。看看样例吧

    第一个人是守卫1到3,第二个人是守卫4到5,最后一个守卫1到1,这就是这道题比较骚的地方了,没错这个1不是代表时间点,而应该是时间段,

    我们可以理解为,第一个人从1点开始持续守卫三个小时,即从1点到4点,第二个人从4点开始守卫2小时,即从4点到6点,最后一个人从1点开始守卫1小时,从1点到2点

    所以建图要注意一下。。。

    另外可能会注意到,比如覆盖是1-4,2-6这两个人,那又要怎么让这两个人有关联呢。。。。开始可能回想连下4-2之类的。。但是万一连续几个人的时间段都是这样不完全重合呢。。。例如1-5,2-6,3-7,4-8,这种情况下,我们可以再反向连几条权值为0的边。。。连为2——1,3——2,4——3,i——i-1这样就可以走通了

    用最后一个例子来解释一下就是:

    假设我吗要从1到7,就可以1-5,然后5-4,然后4-3,最后3-7.。。。这条路径上的5-4,4-3权值为0.。。这样建图后就可以简单跑个SPFA就完成了

    当然这道题的方法很多,dalao们可以多加尝试,当时还想了一个区间dp的方法,不过最后这个方法因为我的状态定义问题最后还是搁浅了

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<iostream>
     5 #include<queue>
     6 #include<cmath>
     7 #include<cstdlib>
     8 #define maxe 10005
     9 #define maxn 90005
    10 using namespace std;
    11 
    12 struct edge{
    13     int u,v,w,nxt;
    14 }e[maxn*10];
    15 
    16 int n,tot,s,t,head[maxn],vis[maxn],dis[maxn],inq[maxn];
    17 
    18 void adde(int u,int v,int w){
    19     tot++;
    20     e[tot].u=u;
    21     e[tot].v=v;
    22     e[tot].w=w;
    23     e[tot].nxt=head[u];
    24     head[u]=tot;
    25 }
    26 
    27 queue<int >q;
    28 
    29 void spfa(int s,int t)
    30 {
    31     memset(dis,-1,sizeof(dis));
    32     dis[s]=0;q.push(s);inq[s]=1;
    33     while(!q.empty())
    34     {
    35         int u=q.front();
    36         q.pop();inq[u]=0;
    37         for(int i=head[u];i!=-1;i=e[i].nxt){
    38             int v=e[i].v,w=e[i].w;
    39             //printf("
    %d  %d  %d
    ",e[i].u,e[i].v,e[i].w);
    40             if((dis[v]>dis[u]+w&&dis[v]!=-1)||(dis[v]==-1)){
    41                 dis[v]=dis[u]+w;
    42                 if(inq[v]==0){
    43                     q.push(v);inq[v]=1;
    44                 }
    45             }
    46         }    
    47     }
    48     if(dis[t]!=-1)printf("%d",dis[t]);
    49     else printf("-1");
    50 }
    51 
    52 int main()
    53 {
    54     memset(head,-1,sizeof(head));
    55     scanf("%d%d%d",&n,&s,&t);t++;
    56     for(int i=1;i<=n;i++){
    57         int u,v,w;
    58         scanf("%d%d%d",&u,&v,&w);v++;
    59         adde(max(u,s),min(v,t),w);
    60     }
    61     for(int i=s;i<t;i++){
    62         adde(i+1,i,0);
    63     }
    64     spfa(s,t);
    65         
    66 }
    View Code
  • 相关阅读:
    模糊查询(排除%等通配符并支持不连续关键字查询)
    ideal中运行manven常用操作
    ideal项目启动及问题
    FastJSON 转换List<T> ,Map<T,T>泛型失败 处理方法
    MySQL的SELECT ...for update
    CouchDB客户端开发—Java版
    Spring Data JPA 实例查询
    第一章 计算机网络概述
    第二章 物理层(二)
    Java常考面试题(一)
  • 原文地址:https://www.cnblogs.com/Danzel-Aria233/p/7652824.html
Copyright © 2020-2023  润新知