CF1204(最短路+思维)
Anna, Svyatoslav and Maps - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
首先用floyd跑一遍最短路。
对于p序列的两个点:如果 dis[p[i]][p[j]] = j-i,则序列p是经过 p[i]~p[j]的最短路.
假设现在存入 v 数组的最后一个点是p[i],找到p[i]后第一个点,使得 dis[p[i]][p[j]] < j - i,此时把 p[j]存入v数组,就不满足题意的:p是按顺序经过v的最短路径之一。
显然p[i+1],p[i+2]~p[j-1]是符合v数组的条件的,但为了让 v 的长度最短,我们只用将 p[j-1] 存入v数组,这样同时满足 dis[p[i]][p[j-1]] = (j-1)-i,dis[p[j-1]][p[j]]=j-(j-1)。
最后再将p[n]存入v数组。
Code:
#include<bits/stdc++.h> using namespace std; #define ll long long #define mp make_pair #define pb push_back #define popb pop_back #define fi first #define se second const int N=150; const int M=1e6+10; const int inf=0x3f3f3f3f; //const ll INF=0x3ffffffffffff; int T,n,m,dis[N][N],p[M]; char s[N][N]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } int main() { // freopen("","r",stdin); // freopen("","w",stdout); n=read(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=inf; for(int i=1;i<=n;i++) dis[i][i]=0; for(int i=1;i<=n;i++) scanf("%s",s[i]+1); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(s[i][j]=='1') dis[i][j]=1; for(int k=1;k<=n;k++) for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); m=read(); for(int i=1;i<=m;i++) p[i]=read(); vector<int> v; v.pb(1); for(int i=2;i<=m;i++) if(dis[p[v.back()]][p[i]]<i-v.back()) v.pb(i-1); v.pb(m); printf("%d\n",v.size()); for(auto x:v) printf("%d ",p[x]); return 0; }
分类:
最短路
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?