模拟赛1
9/27(0.5h)+10/1(3h)
T2 看不懂,T3 调成狗。
T1,点数的尽可能少提示性强,往完全图方向想,写了个暴力找不同路径数,发现 i−>n 决定二进制的该位。
T3,删除相邻的边,要求删除后最短路的最大值。显然删除的这条边只可能在最短路的路径上。考虑建最短路径树。对于 fa−>x 这条边肯定要删去。那么删去之后我们肯定是以最短路径要走到 x 的子树外的,然后再走到 1 号点,但是 fa−>x 被封了,所以我们并不知道最短路径如何走。但是考虑子树处理完了,假如 v,v∈treex,显然我们可以先让 x 走到 v,然后看看能不能通过 v 的边走到 z,z 在 x 的子树外,接下来 disz 就是 z−>1 的路径长度了。
那么答案贡献式就是 (disv−disx)+(v−>z)+disz。但是注意,有可能删去之后还不如不删,所以最后再与最开始最短路取个 max。
我们可以考虑维护子树内的点集,这个可以用 vector+启发式合并,然后要维护点是否在子树内,可以用 map+启发式合并,接下来维护 (disv−disx)+(v−>z)+disz 的最小值。拆下,发现就是维护 disv+(v−>z)+disz 的最小值。用个 set+启发式合并维护下,即每次都去找与当前点相邻的点,然后插入。考虑在贡献答案时顺便删去 v 在当前子树内的无用贡献,因为现在在子树内,到了祖先肯定也会在子树内。
这样子是 O(nlog2n) 的。
T1
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#define ll long long
#define int ll
using namespace std;
int rd() {
char ch=getchar(); int f=1,sum=0;
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0') sum=sum*10+ch-'0',ch=getchar();
return sum*f;
}
ll lrd() {
char ch=getchar(); ll f=1,sum=0;
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0') sum=sum*10+ch-'0',ch=getchar();
return sum*f;
}
vector<pair<int,int> >ans;
signed main() {
freopen("review.in","r",stdin); freopen("review.out","w",stdout);
ll n=lrd(); int m=log2(n)+1;
for(int i=1;i<=m+1;i++) {
for(int j=i+1;j<=m+1;j++) ans.push_back(make_pair(i,j));
}
int nw=(1ll<<(m-1)),x=m+1;
while(nw) {
if(n>=nw) {
n-=nw; ans.push_back(make_pair(x,m+2));
}
nw>>=1; --x;
}
printf("%lld %lld\n",m+2,ans.size());
for(int i=0;i<ans.size();i++) printf("%lld %lld\n",ans[i].first,ans[i].second);
return 0;
}
T3
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <map>
#define N (int)(1e6+5)
#define M N
#define inf (1ll<<62)
#define ll long long
#define int ll
using namespace std;
int rd() {
char ch=getchar(); int sum=0,f=1;
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1; ch=getchar();
}
while(ch<='9'&&ch>='0') sum=sum*10+ch-'0',ch=getchar();
return sum*f;
}
ll lrd() {
char ch=getchar(); ll sum=0,f=1;
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1; ch=getchar();
}
while(ch<='9'&&ch>='0') sum=sum*10+ch-'0',ch=getchar();
return sum*f;
}
struct GRAPH {
struct edge {
int nex,to; ll w;
}e[M<<1];
int head[N],cnt;
GRAPH() {
cnt=1;
}
void add_edge(int x,int y,ll z) {
e[++cnt].nex=head[x]; e[cnt].to=y; e[cnt].w=z; head[x]=cnt;
}
}G,T;
bool vis[N];
ll dis[N],val[N];
int fa[N],n,m;
struct node {
int pos; ll d;
bool operator < (const node &rhs) const {
return rhs.d<d;
}
};
vector<int>*g[N];
int eid[N];
priority_queue<node>q;
void dij() {
for(int i=1;i<=n;i++) dis[i]=inf;
q.push((node){1,0}); dis[1]=0;
while(!q.empty()) {
int x=q.top().pos; q.pop();
if(vis[x]) continue; vis[x]=1;
for(int i=G.head[x];i;i=G.e[i].nex) {
int y=G.e[i].to;
if(dis[y]>dis[x]+G.e[i].w) {
dis[y]=dis[x]+G.e[i].w; fa[y]=x; val[y]=G.e[i].w; eid[y]=i;
if(!vis[y]) q.push((node){y,dis[y]});
}
}
}
}
ll tdis[N],ans[N];
void dfs1(int x) {
for(int i=T.head[x];i;i=T.e[i].nex) {
int y=T.e[i].to; tdis[y]=tdis[x]+T.e[i].w; dfs1(y);
}
}
struct node2 {
int x,y,z;
bool operator < (const node2 &rhs) const {
return z<rhs.z;
}
};
map<int,bool>*mp[N];
set<node2>*gg[N];
set<node2>::iterator it,it2;
void dfs2(int x) {
for(int i=T.head[x];i;i=T.e[i].nex) {
int y=T.e[i].to; dfs2(y);
if((*g[y]).size()>(*g[x]).size()) swap(g[x],g[y]),swap(mp[x],mp[y]);
if((*gg[y]).size()>(*gg[x]).size()) swap(gg[x],gg[y]);
for(int j=0;j<(*g[y]).size();j++) (*g[x]).push_back((*g[y])[j]),(*mp[x])[(*g[y])[j]]=1;
for(it=(*gg[y]).begin();it!=(*gg[y]).end();++it) (*gg[x]).insert(*it);
} (*g[x]).push_back(x); (*mp[x])[x]=1; vis[eid[x]]=vis[eid[x]^1]=1;
for(int i=G.head[x];i;i=G.e[i].nex) {
int y=G.e[i].to; (*gg[x]).insert((node2){y,i,tdis[y]+tdis[x]+G.e[i].w});
}
/*for(int i=0;i<(*gg[x]).size();i++) {
int v=(*gg[x])[i].x,ei=(*gg[x])[i].y,z=(*gg[x])[i].z;
if(vis[ei]) continue; if((*mp[x])[v]) continue;
ans[x]=min(ans[x],-tdis[x]+z);
}*/
for(it=(*gg[x]).begin();it!=(*gg[x]).end();) {
int v=(*it).x,ei=(*it).y,z=(*it).z;
if(vis[ei]) {
++it; continue;
}
if((*mp[x])[v]) {
(*gg[x]).erase(it++); continue;
}
ans[x]=-tdis[x]+z; break;
}
vis[eid[x]]=vis[eid[x]^1]=0;
}
/*
void dfs2(int x) {
for(int i=T.head[x];i;i=T.e[i].nex) {
int y=T.e[i].to; dfs2(y);
for(int j=0;j<g[y].size();j++) g[x].push_back(g[y][j]),mp[x][g[y][j]]=1;
for(int j=0;j<gg[y].size();j++) gg[x].push_back(gg[y][j]);
} g[x].push_back(x); mp[x][x]=1; vis[eid[x]]=vis[eid[x]^1]=1;
for(int i=G.head[x];i;i=G.e[i].nex) {
int y=G.e[i].to; gg[x].push_back((node2){y,i,tdis[y]+tdis[x]+G.e[i].w});
}
for(int i=0;i<gg[x].size();i++) {
int v=gg[x][i].x,ei=gg[x][i].y,z=gg[x][i].z;
if(vis[ei]) continue; if(mp[x][v]) continue;
ans[x]=min(ans[x],-tdis[x]+z);
}
vis[eid[x]]=vis[eid[x]^1]=0;
}
*/
signed main() {
// freopen("rebirth.in","r",stdin); freopen("rebirth.out","w",stdout);
rd(); n=rd(); m=rd(); int x,y; ll z;
for(int i=1;i<=m;i++) x=rd(),y=rd(),z=lrd(),G.add_edge(x,y,z),G.add_edge(y,x,z);
dij(); for(int i=1;i<=n;i++) ans[i]=inf,gg[i]=new set<node2>,g[i]=new vector<int>,mp[i]=new map<int,bool>; memset(vis,0,sizeof(vis));
for(int i=2;i<=n;i++) {
// printf("%lld %lld %lld\n",fa[i],i,val[i]);
T.add_edge(fa[i],i,val[i]);
}
dfs1(1); dfs2(1); ans[1]=0; for(int i=1;i<=n;i++) ans[i]=max(ans[i],tdis[i]),printf("%lld ",ans[i]==inf?-1:ans[i]);
return 0;
}
/*
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <set>
#include <queue>
#include <map>
#define N (int)(2e5+5)
#define M (int)(5e5+5)
#define inf (1ll<<62)
#define ll long long
#define int ll
using namespace std;
int rd() {
char ch=getchar(); int sum=0,f=1;
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1; ch=getchar();
}
while(ch<='9'&&ch>='0') sum=sum*10+ch-'0',ch=getchar();
return sum*f;
}
ll lrd() {
char ch=getchar(); ll sum=0,f=1;
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1; ch=getchar();
}
while(ch<='9'&&ch>='0') sum=sum*10+ch-'0',ch=getchar();
return sum*f;
}
struct GRAPH {
struct edge {
int nex,to; ll w;
}e[M<<1];
int head[N],cnt;
GRAPH() {
cnt=1;
}
void add_edge(int x,int y,ll z) {
e[++cnt].nex=head[x]; e[cnt].to=y; e[cnt].w=z; head[x]=cnt;
}
}G,T;
bool vis[N];
ll dis[N],val[N];
int fa[N],n,m;
struct node {
int pos; ll d;
bool operator < (const node &rhs) const {
return rhs.d<d;
}
};
vector<int>g[N];
int eid[N];
priority_queue<node>q;
void dij() {
for(int i=1;i<=n;i++) dis[i]=inf;
q.push((node){1,0}); dis[1]=0;
while(!q.empty()) {
int x=q.top().pos; q.pop();
if(vis[x]) continue; vis[x]=1;
for(int i=G.head[x];i;i=G.e[i].nex) {
int y=G.e[i].to;
if(dis[y]>dis[x]+G.e[i].w) {
dis[y]=dis[x]+G.e[i].w; fa[y]=x; val[y]=G.e[i].w; eid[y]=i;
if(!vis[y]) q.push((node){y,dis[y]});
}
}
}
}
ll tdis[N],ans[N];
void dfs1(int x) {
for(int i=T.head[x];i;i=T.e[i].nex) {
int y=T.e[i].to; tdis[y]=tdis[x]+T.e[i].w; dfs1(y);
}
}
map<int,bool>mp[N];
struct node2 {
int x,y,z;
};
vector<node2>gg[N];
void dfs2(int x) {
for(int i=T.head[x];i;i=T.e[i].nex) {
int y=T.e[i].to; dfs2(y);
for(int j=0;j<g[y].size();j++) g[x].push_back(g[y][j]),mp[x][g[y][j]]=1;
for(int j=0;j<gg[y].size();j++) gg[x].push_back(gg[y][j]);
} g[x].push_back(x); mp[x][x]=1; vis[eid[x]]=vis[eid[x]^1]=1;
for(int i=G.head[x];i;i=G.e[i].nex) {
int y=G.e[i].to; gg[x].push_back((node2){y,i,tdis[y]+tdis[x]+G.e[i].w});
}
for(int i=0;i<gg[x].size();i++) {
int v=gg[x][i].x,ei=gg[x][i].y,z=gg[x][i].z;
if(vis[ei]) continue; if(mp[x][v]) continue;
ans[x]=min(ans[x],-tdis[x]+z);
}
vis[eid[x]]=vis[eid[x]^1]=0;
}
signed main() {
freopen("rebirth.in","r",stdin); freopen("rebirth.out","w",stdout);
rd(); n=rd(); m=rd(); int x,y; ll z;
for(int i=1;i<=m;i++) x=rd(),y=rd(),z=lrd(),G.add_edge(x,y,z),G.add_edge(y,x,z);
dij(); for(int i=1;i<=n;i++) ans[i]=inf; memset(vis,0,sizeof(vis));
for(int i=2;i<=n;i++) {
// printf("%lld %lld %lld\n",fa[i],i,val[i]);
T.add_edge(fa[i],i,val[i]);
}
dfs1(1); dfs2(1); ans[1]=0; for(int i=1;i<=n;i++) ans[i]=max(ans[i],tdis[i]),printf("%lld ",ans[i]==inf?-1:ans[i]);
return 0;
}*/
__EOF__

本文作者:F x o r G
本文链接:https://www.cnblogs.com/xugangfan/p/15872343.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/xugangfan/p/15872343.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】