首页 > 其他分享 >CF1810E 题解

CF1810E 题解

时间:2023-04-07 12:22:19浏览次数:45  
标签:cnt int 题解 点权 u1 CF1810E vis 复杂度

一、题目描述:

  给你一个 n 个点,m 条边的无向图,点带权,起点可任意选择。

  每走过一个新的点,你的能力值会 +1 。一开始你的能力值为 0 。

  你只能经过点权小于等于你能力值的点。每条边,每个点都可以经过无限次,问能否走遍整个图。

  如果可以,输出 "YES" 。否则输出 "NO" 。有 t 组数据,保证 n 的总和,m 的总和都不超过 2e5 ,t <= 1e3 。


二、做题思路:

  很明显,你只能选择点权为 0 的点作为起点。枚举每个点权为 0 的点,跑一边 dij ,时间复杂度 O(n*nlogm),显然超时。

  考虑优化,之前已经访问过的点再用作起点肯定不优(这里不做解释)。用一个 vis 数组标一下。

  每次 dij 不能 O(n) 的初始化,判定一个点 u 这一轮是否访问过的时候可以判 if (vis[u]==s),其中 s 为起点。

  现在时间复杂度已经是 O(nlogm) 了。复杂度不好直接说明,放个图:

        

 

  假设一开始枚举的点是中间那个 0 ,一共可以拓展到 4 个点 (红点) 。周围被点权较大的点所包围,无法再拓展。

  如果重复拓展到这几个点,那么一定是经过了点权较大的点,此时经过的点 (蓝点) 一定大于 4 个 ,才能通过点权较大的点。

  由此可以发现,总拓展点数最大为 n+n/2+n/4+n/8+...,小于等于 2n 。时间复杂度最差 O(2nlogm),可以通过。


三、完整代码:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<queue>
 4 #define N 200010
 5 using namespace std;
 6 int T,n,m,u1,v1,now,c[N],vis[N];
 7 struct EDGE{
 8     int v,nxt;
 9 }edge[N*2];
10 int head[N],cnt;
11 void add(int u,int v)
12 {
13     edge[++cnt].v=v;
14     edge[cnt].nxt=head[u];
15     head[u]=cnt;
16 }
17 struct node{
18     int pos,dis;
19     bool operator < (const node &t)const{
20         return t.dis<dis;
21     }
22 };
23 priority_queue <node> q;
24 int dij(int s)
25 {
26     while(!q.empty())
27         q.pop();q.push({s,0});now=0;
28     while(!q.empty())
29     {
30         int u=q.top().pos;q.pop();
31         if(vis[u]==s)    continue;vis[u]=s;
32         if(now<c[u])    return 0;    now++;
33         for(int i=head[u];i!=-1;i=edge[i].nxt)
34             q.push({edge[i].v,c[edge[i].v]});
35     }
36     return now==n;
37 }
38 void solve()
39 {
40     cin>>n>>m;cnt=0;
41     for(int i=1;i<=n;i++)
42     {
43         cin>>c[i];
44         head[i]=-1,vis[i]=0;
45     }
46     for(int i=1;i<=m;i++)
47     {
48         cin>>u1>>v1;
49         add(u1,v1),add(v1,u1);
50     }
51     for(int i=1;i<=n;i++)
52         if(!c[i]&&!vis[i]&&dij(i))
53         {
54             cout<<"YES"<<'\n';
55             return ;
56         }
57     cout<<"NO"<<'\n';
58 }
59 int main()
60 {
61     ios::sync_with_stdio(false);
62     cin.tie(0);cout.tie(0);
63     cin>>T;
64     for(int i=1;i<=T;i++)
65         solve();
66     return 0;
67 }

四、写题心得:

  这个题写起来不难,就是时间复杂度难以证明。不过自己花了这么多时间证出来了(头一次配了图 ! ),也是真的很高兴。拜拜!

标签:cnt,int,题解,点权,u1,CF1810E,vis,复杂度
From: https://www.cnblogs.com/yhy-trh/p/17295763.html

相关文章

  • 洛谷P1552 [APIO2012] 派遣 题解 左偏树
    题目链接:https://www.luogu.com.cn/problem/P1552题目大意:每次求子树中薪水和不超过\(M\)的最大节点数。解题思路:使用左偏树维护一个大根堆。首先定义一个Node的结构体:structNode{ints[2],c,sz,dis;longlongsum;Node(){};Node(int_c){s......
  • 关于Qt在线安装报错的一些问题解决办法
    事情的起因是,换了一台新电脑,准备安装Qt,突发现安装不了,报错,一共有几种:1.   2.第二种是不能到选择安装的界面   3.第三种是可以选择了,也可以下载安装了,但是卡在一个地方不动了以上3种个人猜测可能是某些网络原因,至于是什么网络原因,大家自行脑补。不多说废话,经过我......
  • 【容斥、状压dp】主旋律 题解
    【清华集训2014】主旋律题解神秘题。题目简述给你一个有向图\(G=(V,E)\)。求有多少\(E\)的子集\(E'\)使得新图\(G'=(V,E')\)是强连通图。强连通图的定义是任意两点\(u,v\)均存在\(u\tov,v\tou\)的路径。\(n\leq15,m\leqn\times(n-1)\)。解题思路......
  • GMOI R2 T2 猫耳小(加强版) 官方题解
    首先特判\(k=0\)的情况,此时的答案为非\(0\)数的个数,改法是将它们全改成\(0\)。再特判\(k\)较大的情况,此时的答案为\(0\)。否则,对于\(k\)大小适中的情况,我们从前往后遍历数组,同时维护当前区间的\(\operatorname{mex}\)值。根据\(\operatorname{mex}\)的定义,显然对......
  • [HAOI2007]理想的正方形【题解】
    题目描述有一个\(a\timesb\)的整数组成的矩阵,现请你从中找出一个\(n\timesn\)的正方形区域,使得该区域所有数中的最大值和最小值的差最小。输入格式第一行为\(3\)个整数,分别表示\(a,b,n\)的值。第二行至第\(a+1\)行每行为\(b\)个非负整数,表示矩阵中相应位置上......
  • 奶牛排队【题解】
    题目描述奶牛在熊大妈的带领下排成了一条直队。显然,不同的奶牛身高不一定相同……现在,奶牛们想知道,如果找出一些连续的奶牛,要求最左边的奶牛\(A\)是最矮的,最右边的\(B\)是最高的,且\(B\)高于\(A\)奶牛。中间如果存在奶牛,则身高不能和\(A,B\)奶牛相同。问这样的奶牛最......
  • AT CODE FESTIVAL 2016 Final J 题解
    题目妙妙题!简要题意:给定一个\(n\),有一个\(n\timesn\)的网格图。有\(4n\)个方向\(U/D/L/R_{1,2,\dots,n}\),如下图:对于每个方向,有个限制:数\(x\)。你可以进行\(\lex\)次推棋子,把一个棋子放到当前方向指向的第一格,然后如果原来第一格有棋子,把它放到第二格,如果原来第二......
  • 【问题解决】eclipse cdt debug状态控制台输出中文部分乱码
    问题复现使用eclipsecdt版本写了一个C代码简易输出的程序如下:#include<stdio.h>#include<stdlib.h>voidprintln(chararr[]){ inti=0; while(arr[i]!='\0'){ printf("%c",arr[i]); i++; } printf("\n");}intmain(void){......
  • FWT & FMT & 集合幂级数 题解集
    CF449DJzzhuandNumbers简要题意给定序列\(\{a_n\}\),求有多少个子序列满足所有元素的按位与为\(0\)。题解F1考虑FWT的与卷积形式,构造序列\(\{A_n\}\),使\(A_i=\displaystyle\sum_{j\&i=i}a_i\),记\(B_i=\displaystyle\sum_{b\ina}[(b_1\&b_2\&\cdots\&b_n)\&......
  • 2023GPLT选拔题解
    看到没有题解我就给大家浅浅的写一篇吧,如果有错误,希望大家可以帮我指出来哦,创作不易,如果大家给个关注,点个赞就更好了  1:著名开源操作系统Linux的核心创始人Linus有一句经典名言:”Talkischeap.Showmethecode.“ 说出这句话时是2000年8月25日,那天有人在Linus的Linu......