2018.9.7南海中学测试T2 (二分答案)

B疫情延迟
Description
由于A 学校生物实验室里那个不负责的数据分析员,实验室的病毒威力被错误估算,导致了可怕的病毒泄漏,现在病毒即将在校园内传播开来。
校园里一共有n 个建筑物,生物实验室总是位于一号建筑物且在0 时刻受到病毒入侵。这n 个建筑物由m 条单向道路相连(也有可能有建筑物被孤立)。每条道路有两个信息:它的长度,它是多少年前修建的。当一个建筑物被病毒入侵,从被入侵的时刻起,病毒会从所有由这个建筑物通向其他建筑物的道路按着这条道路的方向以1 个单位每秒的速度行进。
校长得知这个事情后,决定放弃这个学校逃跑。校长总是位于编号为n 的行政楼,从零时刻开始需要共T 秒来逃出行政楼,且逃出行政楼即视为逃出了这个学校。也就是说,如果病毒入侵行政楼的时间不小于T,则校长能够成功逃离。
有些时候,校长没有足够的时间逃离,因为病毒到达行政楼的时间太快了。
为了让校长能够逃离学校,不得不拆除校园内的一些道路以延缓行政楼的被入侵时间(拆除道路视为在0 时刻被拆的道路全部消失)。当然,如果使得病毒根本无法到达行政楼,也是可以的。
但是,拆除道路会影响学校的历史气息,且破坏程度定义为拆除的道路中最古老的一条的年龄。请求出保证校长能够安全撤离的情况下,最小的破坏程度。
Input
第一行包含三个整数:n, m, T。
接下来m 行,每行描述一条有向道路。每行4 个整数,si, ti, Li, Yi,分别表示这条道路的起点,终点,长度,这条道路的年龄。
Output
如果不需要拆除任何道路,输出一行两个数:-1 和行政楼的被感染时刻(当然这个时刻大于等于T),以空格隔开。
否则输出一行包含一个数:最小的破坏程度。
Sample Input
【样例输入1】
5 5 15
1 2 6 35
2 4 8 40
1 3 6 45
3 4 3 25
4 5 5 50
【样例输入2】
3 2 10
1 2 5 30
2 3 6 50
Sample Output
【样例输出1】
25
【样例输出2】
-1 11
Hint
【样例解释1】
每条边上的黑字对应这条路的长度,红字对应年龄。校长将在第15 秒逃出学校,
如果不拆除任何道路,行政楼将在第14 秒受到入侵。你可以拆除4 到5 的道路,
使得行政楼免于入侵,这样的破坏程度是50。但是最好的方法是拆掉3 到4 之间的道路,这样使得行政楼在第19 秒受到入侵,校长就可以逃离了。
【数据范围】
对于20%的数据,n, m<=10
对于60%的数据,n, m<=100.
对于100%的数据,n<=20000, m<=100000.
数据保证在不拆除任何道路的情况下,从1 号楼到n 号楼一定存在路径。


所以,就要开始说一说读题的重要性了。
一开始我没有看完题目,然后直接就照着数据去试,然后,我把题目理解成了,将所有删掉的路的文化值加起来,保证最后的文化值的和是最小。然而,最后只对了样例emmmmm。

所以,这道题目的题意到底是什么意思呢?
就是有个病毒,从1号楼出发,每秒走一步,要走到n号楼去感染校长。然后校长要离开n号楼,离开n号楼校长就安全了。然后也就是只要1号楼到n号楼的最短路径大于等于校长离开n号楼的时间,校长就安全了。
然后你可以拆掉一些路,每条路都有文化值,你要拆掉一些路,使病毒不能走这条路,所以病毒去n号楼的时间就会变长。然后整个的破坏程度就是你拆的路的最大的文化值,要你求出最小的破坏程度是多少。

我就是看错题,以为破坏程度是拆掉的路的总和,所以在SPFA松弛时就保存最小文化值的边,然后删去。如果删去后校长还是不安全,继续删。然而这样是错的。

看看题目,最终求的只是所有路中的其中一个文化值,因为低于这个最后文化值的道路都是不用的,也就是删去的。所以这样就可以想到,用二分答案

二分答案,将所有边按照文化值排序,每次取中间的文化值,如果这个文化值一下都路都不用,但是病毒能威胁到校长,就找比这个文化值更大的路。如果不能威胁校长,那么再寻找是否有更小的文化值不能威胁校长。所以就这样子二分,最终找出答案就ok了。

现在的我最主要是,没有好好读题。然后我也不知道如果我读懂题目了,能不能想到这道题用二份答案。所以,做的题目还是有点少,遇到一次就总结一次经验吧。

贴上我的代码:

#include<iostream>
#include<stdio.h>
#include<queue>
#include<algorithm>
using namespace std;
const int oo=0x3f3f3f3f;
struct PATH{
    int si,ti,li,yi;
}path[100005];
int n,m,T,pi,min_k,ans,mid,out;
bool vis[20005];
int p[20005];
int last[20005];
int cost[20005];
int nxt[100005];
int to[100005];
int li[100005];
int yi[100005];

void read();
void SPFA();
void work();
bool cmp(PATH i,PATH j)
{
    return i.yi<j.yi;
}

int main()
{
    read();

    int l=1,r=m;
    SPFA();
    if(cost[n]>=T)
    {
        printf("-1 %d",cost[n]);
        return 0;
    } 
    sort(path+1,path+m+1,cmp);
    while(l<=r)
    {
        mid=l+r>>1;
        out=path[mid].yi;
        SPFA();
        if(cost[n]>=T)
          r=mid-1;
        else
          l=mid+1;

    }
    printf("%d",path[l].yi);
    return 0;
}

void SPFA()
{   
    for(int i=1;i<=n;i++)
      cost[i]=oo;
    queue<int> q;
    while(!q.empty())
      q.pop();
    q.push(1);
    vis[1]=true;
    cost[1]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=false;
        int k=p[u];
        while(k>0)
        {
            int v=to[k];
            int lim=li[k];
            if(yi[k]<=out)
              lim=oo;
            if(cost[v]>=cost[u]+lim)
            {
                if(!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
                cost[v]=cost[u]+lim;
            }
            k=nxt[k];
        }
    }
}
void read()
{
    freopen("b.in","r",stdin);
    freopen("b.out","w",stdout);
    scanf("%d%d%d",&n,&m,&T);
    for(int i=1;i<=m;i++)
    {
        int s,t,l,y;
        scanf("%d%d%d%d",&s,&t,&l,&y);
        pi++;
        nxt[pi]=p[s];
        p[s]=pi;
        to[pi]=t;
        li[pi]=l;
        yi[pi]=y;
        path[i].si=s;
        path[i].ti=t;
        path[i].li=l;
        path[i].yi=y;
    }
    li[min_k]=oo;
}
全部评论

相关推荐

从输入URL到页面加载发生了什么:总体来说分为以下几个过程:&nbsp;1.DNS解析&nbsp;2.TCP连接&nbsp;3.发送HTTP请求&nbsp;4.服务器处理请求并返回HTTP报文&nbsp;5.浏览器解析渲染页面&nbsp;6.连接结束。简述了一下各个过程的输入输出作用:以下是对从输入&nbsp;URL&nbsp;到页面加载各过程的输入、输出或作用的一句话描述:DNS&nbsp;解析:&nbsp;输入:用户在浏览器地址栏输入的域名(如&nbsp;www.example.com)。输出:对应的&nbsp;IP&nbsp;地址(如&nbsp;192.168.1.1)。作用:将易于记忆的域名转换为计算机能够识别和用于网络通信的&nbsp;IP&nbsp;地址,以便浏览器与目标服务器建立连接。TCP&nbsp;连接:&nbsp;输入:浏览器获得的服务器...
明天不下雨了:参考一下我的说法: 关键要讲出输入网址后涉及的每一个网络协议的工作原理和作用: 涉及到的网络协议: HTTP/HTTPS协议->DNS协议->TCP协议->IP协议->ARP协议 面试参考回答: 第一次访问(本地没有缓存时): 一般我们在浏览器地址栏输入的是一个域名。 浏览器会先解析 URL、解析出域名、资源路径、端口等信息、然后构造 HTTP 请求报文。浏览器新开一个网络线程发起HTTP请求(应用层) 接着进行域名解析、将域名解析为 IP 地址 浏览器会先检查本地缓存(包括浏览器 DNS 缓存、操作系统缓存等)是否已解析过该域名 如果没有、则向本地 DNS 服务器请求解析; 本地服务器查不到会向更上层的 DNS 服务器(根域名服务器->顶级域名服务器->权威域名服务器询问)递归查询 最终返回该域名对应的 IP 地址。(应用层DNS协议)DNS 协议的作用: 将域名转换为 IP 地址。 由于 HTTP 是基于 TCP 传输的、所以在发送 HTTP 请求前、需要进行三次握手、在客户端发送第一次握手的时候、( 浏览器向服务器发送一个SYN(同步)报文、其中包含客户端的初始序列号。TCP头部设置SYN标志位、并指定客户端端口 同时填上目标端口和源端口的信息。源端口是浏览器随机生成的、目标端口要看是 HTTP 还是 HTTPS、如果是 HTTP 默认目标端口是 80、如果是 HTTPS 默认是 443。(传输层) 然后到网络层:涉及到(IP协议) 会将TCP报文封装成IP数据包、添加IP头部,包含源IP地址(浏览器)和目标IP地址(服务器)。IP 协议的作用: 提供无连接的、不可靠的数据包传输服务。 然后到数据链路层、会通过 ARP 协议、获取目标的路由器的 MAC 地址、然后会加上 MAC 头、填上目标 MAC 地址和源 MAC 地址。 然后到物理层之后、直接把数据包、转发给路由器、路由器再通过下一跳、最终找到目标服务器、然后目标服务器收到客户的 SYN 报文后,会响应第二次握手。 当双方都完成三次握手后、如果是 HTTP 协议、客户端就会将 HTTP 请求就会发送给目标服务器。如果是 HTTPS 协议、客户端还要和服务端进行 TLS 四次握手之后、客户端才会将 HTTP 报文发送给目标服务器。 目标服务器收到 HTTP 请求消息后、就返回 HTTP 响应消息、浏览器会对响应消息进行解析渲染、呈现给用户
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务