题目传送门(内部题115)


输入格式

  第一行两个正整数$n,m$。
  接下来$m$行,每行$4$个正整数$u_j,v_j,L_j,R_j$。
  接下来一行$n$个数,若第$i$个数为$1$,则$i$号同学最后学会了毒瘤算法;若第$i$个数为$-1$,则$i$号同学最后没有学会毒瘤算法。若第$i$个数为$0$,则不知道$i$号同学最后是否学会了毒瘤算法。


输出格式

  若结果不可能出现,输出一行$Impossible$;否则,输出$m$行,第$j$行一个正整数表示第$j$条信息中的两名同学在哪一天共用午餐。


样例

样例输入1:

4 3
1 2 1 2
2 3 1 2
2 4 1 2
1 0 1 -1

样例输出1:

2
2
1

样例输入2:

4 4
1 2 1 2
2 3 2 3
2 4 1 2
3 4 3 4
1 0 1 -1

样例输出2:

Impossible


数据范围与提示

  本题采用子任务评分。仅当你通过一个子任务下所有测试点时,你才能获得该子任务的分数。
  对于所有数据,$1\leqslant n,m\leqslant 200,000,1\leqslant u_j,v_j\leqslant n,u_j\neq v_j,1\leqslant L_i\leqslant R_i\leqslant 10^9$。
  $1.$($10$分)$n,m\leqslant 12,R_i\leqslant 3$。
  $2.$($15$分)$m=n-1$,且共用午餐的关系将所有同学连接到了一起。
  $3.$($15$分)不存在确定没有学会毒瘤算法的同学。
  $4.$($20$分)$n,m\leqslant 2,000$。
  $5.$($40$分)没有特殊限制。


题解

在没有限制的情况下(不存在确定没有学会毒瘤算法的同学),显然贪心的选择最早学更优。

那么现在我们考虑有没有学会毒瘤算法的同学的情况。

不妨设$sec[i]$表示$i$点最早学会毒瘤算法的时间,那么没有学会毒瘤算法的同学付成$inf$即可。

对于一个转移向这个同学的同学,其$sec$即为这条转移边的$l+1$,因为这两名同学可以在$l$时刻吃饭。

这个过程可以用类似最短路的思想解决。

剩余情况下尽可能早的吃饭一定更优,注意边界即可。

时间复杂度:$\Theta(n\log n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. struct rec{int nxt,to,l,r;}e[400001];
  4. struct node{int x,y,l,r;}b[200001];
  5. int head[200001],cnt;
  6. int n,m;
  7. int a[200001];
  8. int sec[200001],dis[200001];
  9. bool vis[200001];
  10. priority_queue<pair<int,int>>qs;
  11. priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>qt;
  12. void add(int x,int y,int l,int r){e[++cnt]=(rec){head[x],y,l,r};head[x]=cnt;}
  13. void Dij()
  14. {
  15. while(qs.size())
  16. {
  17. int x=qs.top().second;
  18. qs.pop();
  19. if(vis[x])continue;
  20. vis[x]=1;
  21. for(int i=head[x];i;i=e[i].nxt)
  22. {
  23. if(e[i].r<sec[x]&&sec[e[i].to]<=e[i].l)
  24. {
  25. sec[e[i].to]=e[i].l+1;
  26. qs.push(make_pair(sec[e[i].to],e[i].to));
  27. }
  28. }
  29. }
  30. }
  31. void DIJ()
  32. {
  33. memset(dis,0x3f,sizeof(dis));
  34. memset(vis,0,sizeof(vis));
  35. qt.push(make_pair(0,1));
  36. dis[1]=0;
  37. while(qt.size())
  38. {
  39. int x=qt.top().second;
  40. qt.pop();
  41. if(vis[x])continue;
  42. vis[x]=1;
  43. for(int i=head[x];i;i=e[i].nxt)
  44. {
  45. int maxn=max(max(sec[e[i].to],e[i].l),dis[x]);
  46. if(maxn<dis[e[i].to]&&maxn<=e[i].r)
  47. {
  48. dis[e[i].to]=maxn;
  49. qt.push(make_pair(dis[e[i].to],e[i].to));
  50. }
  51. }
  52. }
  53. }
  54. int main()
  55. {
  56. freopen("lunch.in","r",stdin);
  57. freopen("lunch.out","w",stdout);
  58. scanf("%d%d",&n,&m);
  59. for(int i=1;i<=m;i++)
  60. {
  61. scanf("%d%d%d%d",&b[i].x,&b[i].y,&b[i].l,&b[i].r);
  62. add(b[i].x,b[i].y,b[i].l,b[i].r);
  63. add(b[i].y,b[i].x,b[i].l,b[i].r);
  64. }
  65. for(int i=1;i<=n;i++)
  66. {
  67. scanf("%d",&a[i]);
  68. if(a[i]==-1)
  69. {
  70. sec[i]=0x3f3f3f3f;
  71. qs.push(make_pair(0x3f3f3f3f,i));
  72. }
  73. }
  74. Dij();
  75. DIJ();
  76. for(int i=1;i<=n;i++)if(a[i]==1&&dis[i]==0x3f3f3f3f){puts("Impossible");return 0;}
  77. for(int i=1;i<=m;i++)
  78. {
  79. if(a[b[i].x]==-1&&dis[b[i].y]<=b[i].l){puts("Impossible");return 0;}
  80. if(a[b[i].y]==-1&&dis[b[i].x]<=b[i].l){puts("Impossible");return 0;}
  81. }
  82. for(int i=1;i<=m;i++)
  83. {
  84. if(a[b[i].x]==-1||a[b[i].y]==-1||b[i].r<max(dis[b[i].x],dis[b[i].y]))printf("%d\n",b[i].l);
  85. else printf("%d\n",max(b[i].l,max(dis[b[i].x],dis[b[i].y])));
  86. }
  87. return 0;
  88. }

rp++

[CSP-S模拟测试]:午餐(贪心+最短路)的更多相关文章

  1. [CSP-S模拟测试]:任务分配(最短路+贪心+DP)

    题目传送门(内部题149) 输入格式 每个测试点第一行为四个正整数$n,b,s,m$,含义如题目所述. 接下来$m$行,每行三个非负整数$u,v,l$,表示从点$u$到点$v$有一条权值为$l$的有向 ...

  2. [CSP-S模拟测试]:迷宫(最短路)

    题目传送门(内部题123) 输入格式 输入文件的第一行为四个正整数$n,m,k,d$. 接下来$m$行,每行三个整数$u,v,w$,描述一条无向道路. 输入文件最后一行包含$k$个整数,为$p_0,p ...

  3. [CSP-S模拟测试]:最小距离(最短路)

    题目传送门(内部题97) 输入格式 第一行三个整数$n,m,p$,第二行$p$个整数$x_1\sim x_p$表示特殊点的编号.接下来$m$行每行三个整数$u,v,w$表示一条连接$u$和$v$,长度 ...

  4. [CSP-S模拟测试]:游戏(最短路)

    题目传送门(内部题35) 输入格式 第一行,两个正整数$X,Y$.第二行,三个非负整数$A,B,C$.第三行,一个正整数$N$.接下来$N$行,每行两个非负整数$x_i,y_i$. 输出格式 一行,一 ...

  5. csp-s模拟测试92

    csp-s模拟测试92 关于$T1$:最短路这一定建边最短路. 关于$T2$:傻逼$Dp$这一定线段树优化$Dp$. 关于$T3$:最小生成树+树P+换跟一定是这样. 深入(?)思考$T1$:我是傻逼 ...

  6. csp-s模拟测试99

    csp-s模拟测试99 九九归一直接爆炸. $T1$一眼板子. $T2$一眼语文题(语文的唯一一次$120+$是给模拟出来的可知我的语文能力). $T3$一眼普及题. ?? Hours Later 板 ...

  7. csp-s模拟测试98

    csp-s模拟测试98 $T1$??不是我吹我轻松手玩20*20.$T2$装鸭好像挺可做?$T3$性质数据挺多提示很明显? $One$ $Hour$ $Later$ 这$T1$什么傻逼题真$jb$难调 ...

  8. csp-s模拟测试95

    csp-s模拟测试95 去世场祭. $T1$:这不裸的除法分块吗. $T2$:这不裸的数据结构优化$Dp$吗. $T3$:这不裸的我什么都不会搜索骗$30$分吗. 几分钟后. 这除法分块太劲了..(你 ...

  9. csp-s模拟测试85

    csp-s模拟测试85 $T1$全场秒切没有什么区分度,$T2$全场成功转化题意但是我并不会打,$T3$暴力都没打很遗憾. 100 00:21:49 02:56:35 02:56:49 135 02: ...

随机推荐

  1. LoadRunner之使用JSEESIONID访问网站

    LoadRunner使用笔记 JSESSIONID的含义:https://www.cnblogs.com/caiwenjing/p/8081391.html 1.使用JSESSIONID访问网站 Ac ...

  2. redis 学习(16)-- redis 持久化

    redis 持久化 什么是持久化 redis 将所有数据保持在内存中,对数据的更新将异步地保存在磁盘中 持久化的方式 1. 快照 快照是某时某刻对数据的完整备份. 在: MySQL Dump Redi ...

  3. leecode刷题(23)-- 合并两个有序链表

    leecode刷题(23)-- 合并两个有序链表 合并两个有序链表 将两个有序链表合并为一个新的有序链表并返回.新链表是通过拼接给定的两个链表的所有节点组成的. 示例: 输入:1->2-> ...

  4. div+css布局教程(1)

    margin:Margin属性用于设置两个元素之间的距离. 后面如果只有两个参数的话,第一个表示top和bottom,第二个表示left和right因为0 auto,表示上下边界为0,左右则根据宽度自 ...

  5. MySQL 主从同步架构中你不知道的“坑”(2)

    指定同步库情况 1.binlog_format= ROW模式‍ mysql> use testdb; Database changed mysql> show tables; +----- ...

  6. Vue中全局过滤器期与局部过滤器期的使用

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. new angular 项目的工作区配置文件和应用源文件

    1.工作区配置文件 每个工作空间中的所有项目共享同一个 CLI 配置环境 .该工作空间的顶层包含着全工作空间级的配置文件.根应用的配置文件以及一些包含根应用的源文件和测试文件的子文件夹. 工作空间配置 ...

  8. docker 入门(2)

    1,多容器环境 运行docker容器 进入容器并查看该容器的IP exit退出容器 运行超小的linux的docker镜像alpine 可以看到如果没有提前把镜像pull到本地,直接run的话,它会自 ...

  9. 10、LNMP架构

    1LNMP架构概述 1.1.什么是LNMP  LNMP 是一套技术的组合,L = Linux,N = Nginx,M~ = MySQL,P~ = PHP 1.2.LNMP架构是如何工作的 首先Ngin ...

  10. Rust 基础学习

    所有权: 变量具有唯一所有权.如果一个类型拥有 Copy trait,一个旧的变量在将其赋值给其他变量后仍然可用.除此之外,赋值意味着转移所有权.Rust 不允许自身或其任何部分实现了 Drop tr ...