模拟赛1

9/27(0.5h)+10/1(3h)

T2 看不懂,T3 调成狗。

T1,点数的尽可能少提示性强,往完全图方向想,写了个暴力找不同路径数,发现 i>n 决定二进制的该位。

T3,删除相邻的边,要求删除后最短路的最大值。显然删除的这条边只可能在最短路的路径上。考虑建最短路径树。对于 fa>x 这条边肯定要删去。那么删去之后我们肯定是以最短路径要走到 x 的子树外的,然后再走到 1 号点,但是 fa>x 被封了,所以我们并不知道最短路径如何走。但是考虑子树处理完了,假如 v,vtreex,显然我们可以先让 x 走到 v,然后看看能不能通过 v 的边走到 zzx 的子树外,接下来 disz 就是 z>1 的路径长度了。
那么答案贡献式就是 (disvdisx)+(v>z)+disz。但是注意,有可能删去之后还不如不删,所以最后再与最开始最短路取个 max。

我们可以考虑维护子树内的点集,这个可以用 vector+启发式合并,然后要维护点是否在子树内,可以用 map+启发式合并,接下来维护 (disvdisx)+(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 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   FxorG  阅读(33)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示