题解 回路
其实乱搞能过
正解(粘的题解):
每次从队头取出一个点 后,遍历它连向的所有节点 ,若 已经在队列中且不是 的前驱
那么说明我们已经找到了一条非平凡回路,并且这一定是最短的。此时 的最短路 就是答案
每个点最多入队一遍,因此是 的
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 5010
#define fir first
#define sec second
#define pb push_back
#define ll long long
//#define int long long
int n;
char s[N];
vector<int> e[N];
namespace task1{
queue<int> q;
int back[N], dis[N], ans;
void bfs(int s) {
q.push(s);
// int cnt=0;
while (q.size()) {
int u=q.front(); q.pop();
// ++cnt;
for (auto& v:e[u])
if (dis[v]>dis[u]+1) {
dis[v]=dis[u]+1;
back[v]=u; q.push(v);
}
else if (v!=back[u]) ans=min(ans, dis[u]+dis[v]+1);
}
// cout<<"cnt: "<<cnt<<endl;
}
void solve() {
for (int i=1; i<=n; ++i) {
// cout<<"i: "<<i<<endl;
memset(dis, 0x3f, sizeof(dis));
memset(back, -1, sizeof(back));
dis[i]=0; ans=INF;
bfs(i);
printf("%d\n", ans==INF?-1:(ans+1)/2);
}
}
}
namespace task2{
queue<int> q;
int back[N], dis[N], ans;
void bfs(int s) {
q.push(s);
// int cnt=0;
while (q.size()) {
int u=q.front(); q.pop();
// ++cnt;
if (2*dis[u]>=ans) continue;
if (ans==3) continue;
for (auto& v:e[u])
if (dis[v]>dis[u]+1) {
dis[v]=dis[u]+1;
back[v]=u; q.push(v);
}
else if (v!=back[u]) ans=min(ans, dis[u]+dis[v]+1);
}
// cout<<"cnt: "<<cnt<<endl;
}
void solve() {
for (int i=1; i<=n; ++i) {
// cout<<"i: "<<i<<endl;
memset(dis, 0x3f, sizeof(dis));
memset(back, -1, sizeof(back));
dis[i]=0; ans=INF;
bfs(i);
printf("%d\n", ans==INF?-1:(ans+1)/2);
}
}
}
signed main()
{
freopen("a.in", "r", stdin);
freopen("a.out", "w", stdout);
scanf("%d", &n);
for (int i=2; i<=n; ++i) {
scanf("%s", s+1);
for (int j=1; j<i; ++j) if (s[j]=='1')
e[i].pb(j), e[j].pb(i);
}
if (n<=200) task1::solve();
else task2::solve();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】