当前位置: 首页 > news >正文

寒假集训9——图论

P3916 图的遍历

题目描述

给出 N 个点,M 条边的有向图,对于每个点 v,令 A(v) 表示从点 v 出发,能到达的编号最大的点。现在请求出 A(1),A(2),…,A(N) 的值。

输入格式

第 1 行 2 个整数 N,M,表示点数和边数。

接下来 M 行,每行 2 个整数 Ui​,Vi​,表示边 (Ui​,Vi​)。点用 1,2,…,N 编号。

输出格式

一行 N 个整数 A(1),A(2),…,A(N)。

输入输出样例

输入 #1复制

4 3 1 2 2 4 4 3

输出 #1复制

4 4 3 4

说明/提示

  • 对于 60% 的数据,1≤N,M≤103。
  • 对于 100% 的数据,1≤N,M≤105。

这样会超时,有一个测试点过不了。

其实刚刚开始提交第一版不带标记的代码时,我所有测试点都超时了。标记状态的st数组我是在和科技交流之后才想起来。

这是邻接表的写法,因为1e5的数据范围太大了,开1e5 的二维数组开不了,所以不能用邻接矩阵。但是链式前向星我理解的不是很好,所以就想起了这个邻接表的写法。

当时我第一次写的是vecrtor>,因为我接触到的好像都是链表头插。但是因为超时了,所以就觉得vector好像和list在这题大差不差,就想着用vector能不能优化一下。没想到还是没成功。

#include<iostream> #include<vector> using namespace std; const int N = 1e5 + 10; vector <vector<int>> g(N); void dfs(int cur,int&maxn, vector <bool>& st) { st[cur] = true; { for (auto e : g[cur]) { maxn = max(maxn, e); if(st[e]==false) dfs(e, maxn, st); } } } int main() { int n, m; cin >> n >> m; //m条边 for (int i = 1;i <= m;i++) { int u, v; cin >> u >> v; g[u].push_back(v); } //n个点 for (int i = 1;i <= n;i++) { int maxn = i; int cur = i; //标记访问过的点!!! //st数组不能是全局,必须开局部!!! //并且作为函数参数传递 vector <bool> st(N, false); dfs(cur, maxn, st); cout << maxn << " "; } return 0; }

我现在就想着输入边的时候就顺带更新答案数组,看看可不可行,这样不用建邻接表,也不用dfs。应该不至于超时。但现实证明不行,科技给的解释如下:

1.忽略了传递性(A→B→C 时,A应该能到C)

2.只更新了边的一端

3.没有利用历史信息

最后,借鉴了题解和学长的代码。

反向图+DFS的降维打击 | O(n+m)优雅解法

1.通过反向建图巧妙转化问题

2.利用从大到小的顺序保证正确性

3.使用DFS传播标记高效计算

4.简单的剪枝避免重复计算

AC代码(详细注释版)

#include<iostream> #include<vector> using namespace std; const int N = 1e5 + 10; vector <int> g[N];//存图 int ans[N];//存答案 //正在访问的点,当前传播的值 void dfs(int cur, int val) { //如果当前顶点已经标记过,直接返回 if (ans[cur] != 0) return; //顶点 cur能到达的最大编号是 val ans[cur] = val; for (auto e : g[cur]) dfs(e, val); } int main() { int n, m; cin >> n >> m; //【m条边】 for (int i = 1;i <= m;i++) { int u, v; cin >> u >> v; //建反图!!! g[v].push_back(u); } //【n个点】 for (int i = n;i >= 1;i--) dfs(i, i); //i号点能到达的最大编号至少是自己(i) for (int i = 1;i <= n;i++) cout << ans[i] << " "; return 0; }

AC代码(纯享版)

#include<iostream> #include<vector> using namespace std; const int N = 1e5 + 10; vector <int> g[N]; int ans[N]; void dfs(int cur, int val) { if (ans[cur] != 0) return; ans[cur] = val; for (auto e : g[cur]) dfs(e, val); } int main() { int n, m; cin >> n >> m; for (int i = 1;i <= m;i++) { int u, v; cin >> u >> v; g[v].push_back(u); } for (int i = n;i >=1;i--) dfs(i, i); for (int i = 1;i <= n;i++) cout << ans[i] << " "; return 0; }

B3643 图的存储

题目描述

给定一个 n 个顶点 m 条边的无向图。请以邻接矩阵和邻接表的形式输出这一张图。

输入格式

第一行输入两个正整数 n 和 m,表示图的顶点数和边数。

第二行开始,往后 m 行,每行输入两个以空格隔开的正整数 u,v,表示 u,v 顶点之间有一条边直接相连。

输出格式

首先输出 n 行 n 列的矩阵,以空格隔开每一行之间的数表示邻接矩阵。第 i 行第 j 列的数为 1 则表示顶点 i,j 之间有一条边直接相连;若为 0 则表示没有直接相连的边。

再往后输出 n 行。第 i 行首先先输出一个整数 di​,表示这个顶点的度数,再按照从小到大的顺序,依次输出与顶点 i 直接相连的所有顶点。

输入输出样例

输入 #1复制

5 5 1 2 2 3 3 5 1 3 3 4

输出 #1复制

0 1 1 0 0 1 0 1 0 0 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 2 2 3 2 1 3 4 1 2 4 5 1 3 1 3

说明/提示

样例的图如图所示:

数据保证,对于所有数据,1≤n≤1000,1≤m≤105,且图无重边无自环。

记得排序再输出就行。

#include<iostream> #include<vector> #include<algorithm> using namespace std; const int N = 1e3 + 10; vector <int> glist[N];//邻接表 int gmat[N][N];//邻接矩阵 int degree[N];//度数 int main() { int n, m; cin >> n >> m; for (int i = 1;i <= m;i++) { int u, v; cin >> u >> v; glist[u].push_back(v); glist[v].push_back(u); gmat[u][v] = 1; gmat[v][u] = 1; degree[u]++; degree[v]++; } for (int i = 1;i <= n;i++) { for (int j = 1;j <= n;j++) cout << gmat[i][j] << " "; cout << endl; } for (int i = 1;i <= n;i++) { cout << degree[i] << " "; sort(glist[i].begin(), glist[i].end()); for (int e : glist[i]) cout << e << " "; cout << endl; } return 0; }

11. 路径之谜

题目描述

小明冒充XX星球的骑士,进入了一个奇怪的城堡。

城堡里边什么都没有,只有方形石头铺成的地面。

假设城堡地面是n×n×n个方格。如下图所示。

按习俗,骑士要从西北角走到东南角。可以横向或纵向移动,但不能斜着走,也不能跳跃。每走到一个新方格,就要向正北方和正西方各射一箭。(城堡的西墙和北墙内各有nn个靶子)同一个方格只允许经过一次。但不必走完所有的方格。如果只给出靶子上箭的数目,你能推断出骑士的行走路线吗?有时是可以的,比如上图中的例子。

本题的要求就是已知箭靶数字,求骑士的行走路径(测试数据保证路径唯一)

输入描述

第一行一个整数NN(0≤N≤200≤≤20),表示地面有N×N×N个方格。

第二行NN个整数,空格分开,表示北边的箭靶上的数字(自西向东)

第三行NN个整数,空格分开,表示西边的箭靶上的数字(自北向南)

输出描述

输出一行若干个整数,表示骑士路径。

为了方便表示,我们约定每个小格子用一个数字代表,从西北角开始编号: 0,1,2,3⋯⋯

比如,上图中的方块编号为:

0 1 2 3

4 5 6 7

8 9 10 11

12 13 14 15

输入输出样例

示例

输入

4 2 4 3 4 4 3 3 3

输出

0 4 5 1 2 3 7 11 10 9 13 14 15

运行限制

  • 最大运行时间:5s
  • 最大运行内存: 256M
http://www.jsqmd.com/news/376184/

相关文章:

  • Java毕设项目:基于springboot的文创销售管理系统(源码+文档,讲解、调试运行,定制等)
  • blender 修改物体 修改衣服
  • ue 蓝图添加灯光
  • 2026年常州冷却塔维修厂家权威推荐榜:昆山冷却塔维修/昆山良机冷却塔/杭州良机冷却塔/良机冷却塔维修/良机冷却塔配件/选择指南 - 优质品牌商家
  • ue 框选 多个对象 框选物体
  • 2026年冷却塔厂家公司权威推荐:冷却塔填料更换、圆形冷却塔、常州良机冷却塔、方型冷却塔、无锡良机冷却塔、昆山冷却塔维修选择指南 - 优质品牌商家
  • 力扣第45题:二叉树的右视图
  • Nodejs+vue+ElementUI框架的在线学习资源推荐的设计与实现
  • 2026年开年室内健身器材综合制造厂商权威评测与选型指南 - 2026年企业推荐榜
  • 2026年月嫂培训机构厂家最新推荐:北京正规家政月嫂公司招商连锁加盟、北京正规家政月嫂公司招聘合伙人、北京高端月嫂公司选择指南 - 优质品牌商家
  • Nodejs+vue+ElementUI框架的志愿服务管理系统的设计与实现
  • 商用与家用兼顾:2026江苏健身器材品牌全景观察 - 2026年企业推荐榜
  • NASA 先进的空中交通(AAM)概述 2025
  • Nodejs+vue+ElementUI框架电动车辆充电桩报修管理系统的设计与开发
  • 2026年冷却塔填料更换公司权威推荐:良机冷却塔厂家/良机冷却塔维修/良机冷却塔配件/苏州冷却塔维修/苏州良机冷却塔/选择指南 - 优质品牌商家
  • Nodejs+vue+ElementUI框架的一键选择“搭子”线下社交陪伴聊天系统
  • Nodejs+vue+ElementUI框架二手交易系统的设计与实现
  • 2026年AI客服机器人厂家权威推荐榜:BOSS直聘AI客服机器人、抖音AI客服机器人、VEO视频生成、京东AI客服机器人选择指南 - 优质品牌商家
  • Windows 下 Node.js 重定向输出导致中文乱码的问题分析
  • Nodejs+vue+ElementUI框架共享厨师预约平台的设计与实现
  • 1.77秒克隆了100字!1G显存就能玩语音声音克隆,速度增快150倍,效果不输大模型,LuxTTS离线整合包_封面
  • 2026年AI视频生成厂家最新推荐:文字生成视频AI、电商短视频AI、美团AI客服机器人、营销视频AI制作、视频号AI制作选择指南 - 优质品牌商家
  • 2026年淘宝AI客服机器人厂家最新推荐:BOSS直聘AI客服机器人、商品视频AI生成、小红书AI客服机器人、微信AI客服机器人选择指南 - 优质品牌商家
  • Nodejs+vue+ElementUI框架家庭装修 家装 装饰工程管理系统
  • 2026年抖音AI客服机器人厂家最新推荐:拼多多智能客服/文字生成视频AI/电商短视频AI/美团AI客服机器人/选择指南 - 优质品牌商家
  • 鸣鸣很忙行使超额配股权:额外募资5.5亿港元
  • Tableau+大数据:交互式描述性分析可视化教程
  • Embedded Systems Optimization1(TODO)
  • 京新药业冲刺港股:10个月营收33亿 利润6.29亿 刚派息2.85亿
  • 2026年唐山市选矿设备实力厂家盘点与选购指南 - 2026年企业推荐榜