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

Codeforces Round 1043 (Div. 3) F. Rada and the Chamomile Valley

F.拉达和甘菊谷

每次测试的时间限制:3 秒

每次测试的内存限制512 兆字节

输入:标准输入

输出:标准输出
昨天,拉达发现了一个传送门,可以把她传送到洋甘菊谷,然后再传送回来。拉达的快乐无以言表,但好景不长–她突然意识到,她不知道任何一个斯迈沙里奇人会在何时何地出现。

甘菊谷由 nnn 座房子和连接房子的 mmm 条巷子组成。小巷的编号从 111mmm 。您可以沿着小巷双向行走。众所周知,从任何一栋房子出发,都可以通过小巷到达其他任何一栋房子。此外,任何两栋房子最多只有一条巷子相连。

拉达知道 Smeshariki 每天都会从 111 号房屋步行到 nnn 号房屋,但她不知道他们具体会走哪条巷子。在接下来的 qqq 天里,拉达每天都会去甘菊谷。在 kkk 这一天,她会去 ckc_kck 号房子。

由于拉达不知道斯梅斯哈里基会走哪条具体的巷子,所以她只对那些他们***肯定会走的巷子感兴趣。为了确保不会错过任何一条,她想知道每天最近的此类车道的索引。拉达忙于漫步甘菊谷,所以她请您帮她确定所需的车道指数。

从房屋 ccc 到连接房屋 aaabbb 的车道的距离定义为 ρ(a,c)\rho(a, c)ρ(a,c)ρ(b,c)\rho(b, c)ρ(b,c) 的最小值,其中 ρ(a,b)\rho(a, b)ρ(a,b) 是指从房屋编号 aaa 开始到达房屋编号 bbb 所需的最小车道数。
输入

输入的第一行包含一个整数 ttt ( 1≤t≤1041 \leq t \leq 10^41t104 ) - 测试用例的数量。每个测试用例的说明如下。

第一行包含两个整数 nnnmmm ( 1≤n≤2⋅1051 \leq n \leq 2 \cdot 10^51n2105 , n−1≤m≤min⁡(n⋅(n−1)2,2⋅105)n-1 \leq m \leq \min(\frac{n \cdot (n-1)}{2}, 2 \cdot 10^5)n1mmin(2n(n1),2105) )–分别是房屋和车道的数量。

接下来的 mmm 行包含两个整数 u≠vu \neq vu=v1≤u,v≤n1 \leq u, v \leq n1u,vn )–连接编号为 uuuvvv 的房屋的车道。这些巷道是按编号顺序排列的,即先描述第一条巷道,然后是第二条、第三条,依次类推,直到 mmm /第三条巷道。

接下来是一个整数 qqq1≤q≤2⋅1051 \leq q \leq 2 \cdot 10^51q2105 )–拉达将在甘菊谷行走的天数。

接下来的 qqq 行每行都包含一个整数 ccc ( 1≤c≤n1 \leq c \leq n1cn )–拉达当天将在哪所房子里。

可以保证的是,从任何一栋房子出发,只需通过小巷就可以到达其他任何一栋房子,而从一栋房子到它自己之间是没有小巷的,任何两栋房子之间最多只有一条小巷相连。

保证所有测试用例的 nnn 之和不超过 2⋅1052 \cdot 10^52105 ,所有测试用例的 mmm 之和不超过 2⋅1052 \cdot 10^52105 ,所有测试用例的 qqq 之和不超过 2⋅1052 \cdot 10^52105
输出

对于每个测试用例,输出每一天的答案。如果任何一天都有多条合适的车道,则输出合适车道中指数的车道。如果没有所需的车道,则输出 −1-11

在所有进一步的解释中,我们将 aaa 号房屋经由 ccc 号巷道到 bbb 号房屋的过渡段称为 a→cba \xrightarrow{c} bacb

在第一个样本中,从房屋 111 到房屋 333 ,至少可以通过以下路径到达:

1→33 1 \xrightarrow{3} 3 133

1→12→23 1 \xrightarrow{1} 2 \xrightarrow{2} 3 11223

我们可以看到,这两条路径没有共用车道,也就是说没有合适的车道。

在第二个样本中,我们可以看到从 111nnn 有一条唯一的路径:

1→12→23→34→45 1 \xrightarrow{1} 2 \xrightarrow{2} 3 \xrightarrow{3} 4 \xrightarrow{4} 5 112233445

可以看出, vvv -顶点的答案是 max⁡(v−1, 1)\max(v-1,\ 1)max(v1, 1)

  • 解决办法

  • 1、首先我要知道这必经过路径是什么,在一图里面可以叫做桥,(不了解的先去看看怎么求,后面要用)。
  • 2、他是去动物们的必经路径上,而且只能是1−n1 - n1n的路径上,由于是桥,所以我们随便跑一条路,把上面的桥标记一下,这就是他要去的路径。
  • 3、我们把要求路径求出来了,接下来我们可以去广搜,这样就只需O(1)O(1)O(1)时间复杂度输出每一个答案
  • (启发式广搜):因为如果我们每个点去广搜整个图,最后一点会超爆,所以我们在广搜时,在遇到标记了的桥或标记了的桥的两点,就直接pop,因为从这两点出发的点肯定比当前点更优。我提供两份代码,一个判点,一个是判桥。(一定不是我开始判桥错了,去判点,后面才把判边改出来
  • 第一篇是判标记了的桥的两边点的

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,FULL=1e15;
struct node{int a,b,id;bool friend operator<(node aa,node bb){return aa.id<bb.id;}
}qiao[N];
int h[N],ans,to[N*2],ne[N*2],id[N*2],n,m,tot,q,dfn[N],low[N],sj;
int dp[N],dis[N],pre1[N],pre2[N];
bool vis[N],vis1[N],vis2[N];
void add(int a,int b,int c)
{tot++;ne[tot]=h[a];h[a]=tot;to[tot]=b;id[tot]=c;
}
void bfs(int u)
{queue<int>q;q.push(u);while(!q.empty()){int j=q.front();q.pop();if(vis2[j]&&j!=u)continue;for(int i=h[j];i;i=ne[i]){int jj=to[i];if(dis[jj]>dis[j]+1){dis[jj]=dis[j]+1;dp[jj]=dp[u];q.push(jj);}}}
}
void spfa(int u)
{vis[u]=1;queue<int>q;q.push(u);while(!q.empty()){int j=q.front();q.pop();// cout<<j<<" ";if(j==n)break;for(int i=h[j];i;i=ne[i]){int jj=to[i];if(!vis[jj]){pre1[jj]=j;pre2[jj]=id[i];q.push(jj);vis[jj]=1;}}}// cout<<'\n'<<"-----------"<<'\n';int jj=n;while(jj!=1){// cout<<jj<<" "<<pre2[jj]<<" ";vis1[pre2[jj]]=1;jj=pre1[jj];}// cout<<'\n'<<"-----------"<<'\n';
}
void tanjian(int u,int fa)
{dfn[u]=low[u]=++sj;for(int i=h[u];i;i=ne[i]){int j=to[i];if(!dfn[j]){tanjian(j,u);low[u]=min(low[u],low[j]);if(low[j]>dfn[u]&&vis1[id[i]]){vis2[u]=1;vis2[j]=1;qiao[++ans].a=u;qiao[ans].b=j;qiao[ans].id=id[i];// cout<<u<<" "<<j<<'\n';}}else if(j!=fa)low[u]=min(low[u],dfn[j]);}
}
signed main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int _,a,b;cin>>_;while(_--){cin>>n>>m;fill(dfn+1,dfn+1+n,0);sj=0;ans=0;tot=0;fill(h+1,h+1+n,0);for(int i=1;i<=m;i++){cin>>a>>b;add(a,b,i);add(b,a,i);}// cout<<ans<<'\n';fill(dis+1,dis+1+n,FULL);fill(vis+1,vis+1+n,0);fill(vis2+1,vis2+1+n,0);fill(vis1+1,vis1+1+m,0);spfa(1);tanjian(1,0);// cout<<'\n';sort(qiao+1,qiao+1+ans);// cout<<qiao[1].id<<'\n';for(int i=1;i<=ans;i++){// cout<<qiao[i].id<<" "<<vis1[qiao[i].id]<<'\n';if(dis[qiao[i].a]>0)dp[qiao[i].a]=qiao[i].id,dis[qiao[i].a]=0,bfs(qiao[i].a);if(dis[qiao[i].b]>0)dp[qiao[i].b]=qiao[i].id,dis[qiao[i].b]=0,bfs(qiao[i].b);// bfs(qiao[i].a),bfs(qiao[i].b);}cin>>q;while(q--){cin>>a;if(dis[a]==FULL)cout<<"-1"<<" ";elsecout<<dp[a]<<" ";}cout<<'\n';}return 0;
}
  • 第二篇就是判桥的

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5,FULL=1e15;
struct node{int a,b,id;bool friend operator<(node aa,node bb){return aa.id<bb.id;}
}qiao[N];
int h[N],ans,to[N*2],ne[N*2],id[N*2],n,m,tot,q,dfn[N],low[N],sj;
int dp[N],dis[N],pre1[N],pre2[N];
bool vis[N],vis1[N],vis2[N];
void add(int a,int b,int c)
{tot++;ne[tot]=h[a];h[a]=tot;to[tot]=b;id[tot]=c;
}
void bfs(int u)
{queue<int>q;q.push(u);while(!q.empty()){int j=q.front();q.pop();// if(vis2[j]&&j!=u)continue;for(int i=h[j];i;i=ne[i]){if(vis2[id[i]])continue;int jj=to[i];if(dis[jj]>dis[j]+1){dis[jj]=dis[j]+1;dp[jj]=dp[u];q.push(jj);}}}
}
void spfa(int u)
{vis[u]=1;queue<int>q;q.push(u);while(!q.empty()){int j=q.front();q.pop();// cout<<j<<" ";if(j==n)break;for(int i=h[j];i;i=ne[i]){int jj=to[i];if(!vis[jj]){pre1[jj]=j;pre2[jj]=id[i];q.push(jj);vis[jj]=1;}}}// cout<<'\n'<<"-----------"<<'\n';int jj=n;while(jj!=1){// cout<<jj<<" "<<pre2[jj]<<" ";vis1[pre2[jj]]=1;jj=pre1[jj];}// cout<<'\n'<<"-----------"<<'\n';
}
void tanjian(int u,int fa)
{dfn[u]=low[u]=++sj;for(int i=h[u];i;i=ne[i]){int j=to[i];if(!dfn[j]){tanjian(j,u);low[u]=min(low[u],low[j]);if(low[j]>dfn[u]&&vis1[id[i]]){vis2[id[i]]=1;qiao[++ans].a=u;qiao[ans].b=j;qiao[ans].id=id[i];// cout<<u<<" "<<j<<'\n';}}else if(j!=fa)low[u]=min(low[u],dfn[j]);}
}
signed main()
{ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);int _,a,b;cin>>_;while(_--){cin>>n>>m;fill(dfn+1,dfn+1+n,0);sj=0;ans=0;tot=0;fill(h+1,h+1+n,0);for(int i=1;i<=m;i++){cin>>a>>b;add(a,b,i);add(b,a,i);}// cout<<ans<<'\n';fill(dis+1,dis+1+n,FULL);fill(vis+1,vis+1+n,0);fill(vis2+1,vis2+1+m,0);fill(vis1+1,vis1+1+m,0);spfa(1);tanjian(1,0);// cout<<'\n';sort(qiao+1,qiao+1+ans);// cout<<qiao[1].id<<'\n';for(int i=1;i<=ans;i++){// cout<<qiao[i].id<<" "<<vis1[qiao[i].id]<<'\n';if(dis[qiao[i].a]>0)dp[qiao[i].a]=qiao[i].id,dis[qiao[i].a]=0,bfs(qiao[i].a);if(dis[qiao[i].b]>0)dp[qiao[i].b]=qiao[i].id,dis[qiao[i].b]=0,bfs(qiao[i].b);// bfs(qiao[i].a),bfs(qiao[i].b);}cin>>q;while(q--){cin>>a;if(dis[a]==FULL)cout<<"-1"<<" ";elsecout<<dp[a]<<" ";}cout<<'\n';}return 0;
}
http://www.dtcms.com/a/354992.html

相关文章:

  • 02Shell的变量运算以及数据比较
  • 卷积神经网络(一):卷积神经网络基础
  • 基于卷积神经网络 (CNN) 的 MNIST 手写数字识别模型
  • 如果给我们直接创建的类加上索引?和len方法?
  • 深度学习篇---模型参数保存
  • 卷积神经网络实现mnist手写数字集识别案例
  • Apollo-PETRv1演示DEMO操作指南
  • 【Qt】QCryptographicHash 设置密钥(Key)
  • Deeplizard 深度学习课程(四)—— 模型构建
  • jwt原理及Java中实现
  • 海盗王64位dx9客户端修改篇之二
  • 学习Java29天(tcp多发多收)但是无解决客户端启动多个问题
  • ProfiNet 转 Ethernet/IP 柔性产线构建方案:网关技术保护新能源企业现有设备投资
  • LeetCode Hot 100 第7天
  • 第三十天:世界杯队伍团结力问题
  • EF Core 编译模型 / 模型裁剪:冷启动与查询优化
  • QT之双缓冲 (QMutex/QWaitCondition)——读写分离
  • 企业如何管理跨多个系统的主数据?
  • MaxCompute MaxFrame | 分布式Python计算服务MaxFrame(完整操作版)
  • 【Lua】题目小练12
  • 如何实现HTML动态爱心表白效果?
  • 多版本并发控制MVCC
  • 黑马点评|项目日记(day02)
  • C#和Lua相互访问
  • 基于金庸武侠小说人物关系设计的完整 SQL 语句,包括数据库创建、表结构定义和示例数据插入
  • Docker 详解+示例
  • map底层的数据结构是什么,为什么不用AVL树
  • 机器学习回顾(一)
  • 陪诊小程序系统开发:搭建医患之间的温暖桥梁
  • Scrapy 基础介绍