1 条题解
-
0
题目深度分析
问题本质
我们有一个 n 个节点的完全图,但每条边被定向了,形成了一个竞赛图 (tournament graph)。
竞赛图的性质:
- 任意两个不同节点之间恰好有一条有向边
- 可能存在环,但整体结构有很好的性质
关键定理
竞赛图结构定理:任何竞赛图都可以唯一分解为强连通分量 ,满足:
- 每个 是强连通的
- 所有 到 () 的边都是从 指向
这意味着 SCC 形成一个全序链。
路径长度分析
从节点 出发的最长简单路径:
- 如果 ,那么它能到达 中的所有节点
- 不能到达 (因为边方向限制)
所以最长路径长度 =
路径构造方法
对于每个强连通分量 :
- 强连通竞赛图一定有哈密顿圈(经典结论)
- 我们可以构造哈密顿路径
构造算法(增量法):
- 从单个节点开始
- 每次加入一个新节点 :
- 如果 指向路径头,插入开头
- 如果路径尾指向 ,插入末尾
- 否则,找到位置 使得 且 ,插入中间
算法步骤
- 读入并建图:
- 求 SCC:用 Kosaraju 或 Tarjan,
- 拓扑排序 SCC:竞赛图中 SCC 自然有序
- 计算后缀和:每个 SCC 开始的最长路径长度
- 为每个起点构造路径:
核心算法解释
// SCC分解和拓扑排序 void kosaraju() { // 第一次DFS确定完成时间 for(int i=1;i<=n;i++) if(!vis[i]) dfs1(i); // 第二次DFS在反图上找SCC for(int i=n-1;i>=0;i--) { int u=order[i]; if(!vis[u]) dfs2(u,compCount++); } // 拓扑排序SCC:通过比较边方向 sort(SCC,SCC+compCount,[&](int a,int b){ return g[SCC[a][0]][SCC[b][0]]; }); } // 构造哈密顿路径 vector<int> buildPath(vector<int>& nodes) { vector<int> path={nodes[0]}; for(int i=1;i<nodes.size();i++) { int x=nodes[i]; if(g[x][path[0]]) path.insert(path.begin(),x); else if(g[path.back()][x]) path.push_back(x); else { for(int j=0;j+1<path.size();j++) if(g[path[j]][x]&&g[x][path[j+1]]){ path.insert(path.begin()+j+1,x); break; } } } return path; } // 主逻辑 int main() { // 读入建图 cin>>n; for(int i=2;i<=n;i++) for(int j=1;j<i;j++) cin>>g[j][i]; // 1:j->i, 0:i->j kosaraju(); // 计算每个SCC开始能访问的节点总数 vector<int> suffix(compCount+1,0); for(int i=compCount-1;i>=0;i--) suffix[i]=suffix[i+1]+SCC[i].size(); // 为每个起点输出最长路径 for(int start=1;start<=n;start++) { int cid=comp[start]; vector<int> path; for(int i=cid;i<compCount;i++) { auto seg=buildPath(SCC[i]); path.insert(path.end(),seg.begin(),seg.end()); } cout<<suffix[cid]; for(int u:path) cout<<" "<<u; cout<<"\n"; } }
复杂度分析
- 建图:,必须读取所有输入
- Kosaraju:,虽然理论 但
- 构造路径:,每个节点插入需要线性时间
- 总复杂度:,对于 可行
样例验证
以题目样例为例:
4 1 1 1 1 0 1
建图:
1→2, 1→3, 1→4 2→3, 4→2 3→4
SCC 分解:{1}, {2,3,4}
- 从 1 出发:可以访问所有 4 个城市
- 从 2,3,4 出发:只能访问 {2,3,4} 中的 3 个城市
输出:
4 1 2 3 4 3 2 3 4 3 3 4 2 3 4 2 3
完全符合题目要求。
总结
这道题的核心在于理解竞赛图的结构性质:
- SCC 链式排序
- 强连通竞赛图有哈密顿圈
- 从某点出发的最长路径由它所在的 SCC 位置决定
利用这些性质,我们就能高效解决问题。
- 1
信息
- ID
- 3206
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 37
- 已通过
- 1
- 上传者