mirror of
https://gitcode.com/Zengtudor/alg2025.git
synced 2025-10-29 19:42:40 +00:00
Compare commits
2 Commits
e66f06db69
...
9a06eb0821
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9a06eb0821 | ||
|
|
1f4768391d |
62
src/10/2/P4554.cpp
Normal file
62
src/10/2/P4554.cpp
Normal file
@ -0,0 +1,62 @@
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <deque>
|
||||
#include <iostream>
|
||||
#include <istream>
|
||||
using ll = int64_t;
|
||||
#define sl static inline
|
||||
const ll maxn = 505;
|
||||
ll n,m,x1,y1,x2,y2,inf=1e9+7;
|
||||
char c[maxn][maxn];
|
||||
ll ans[maxn][maxn];
|
||||
|
||||
struct P{
|
||||
ll x,y,s;
|
||||
};
|
||||
|
||||
ll dis[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
|
||||
|
||||
sl int solve(){
|
||||
std::cin>>n>>m;
|
||||
if(n==0 && m==0)return 1;
|
||||
for(ll i=0;i<n;i++){
|
||||
for(ll j=0;j<m;j++){
|
||||
std::cin>>c[i][j];
|
||||
ans[i][j]=inf;
|
||||
}
|
||||
}
|
||||
// printf("line = %d\n",__LINE__);
|
||||
std::cin>>x1>>y1>>x2>>y2;
|
||||
std::deque<P> dq;
|
||||
dq.emplace_back(x1,y1,0);
|
||||
while(dq.size()){
|
||||
auto [x,y,s] = dq.front();
|
||||
dq.pop_front();
|
||||
for(ll i=0;i<4;i++){
|
||||
ll nx=x+dis[i][0],ny=y+dis[i][1];
|
||||
if(nx<0||nx>n-1||ny<0||ny>m-1)continue;
|
||||
ll ns = s+(c[x][y]!=c[nx][ny]);
|
||||
if(nx==x2&&ny==y2){
|
||||
std::cout<<ns<<"\n";
|
||||
return 0;
|
||||
}
|
||||
if(ns<ans[nx][ny]){
|
||||
ans[nx][ny]=ns;
|
||||
if(c[x][y]!=c[nx][ny]){
|
||||
dq.emplace_back(nx,ny,ns);
|
||||
}else{
|
||||
dq.emplace_front(nx,ny,s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(){
|
||||
std::iostream::sync_with_stdio(false);
|
||||
std::cin.tie(nullptr);
|
||||
|
||||
while (!solve());
|
||||
}
|
||||
100
src/10/2/P8435.cpp
Normal file
100
src/10/2/P8435.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
const int MAXN = 5e5+5; // 节点数上限
|
||||
|
||||
int n, m;
|
||||
std::vector<int> adj[MAXN]; // 邻接表存图
|
||||
|
||||
int dfn[MAXN], low[MAXN], ts; // Tarjan算法所需的时间戳数组
|
||||
int stk[MAXN], top; // 手动实现的栈,比std::stack稍快
|
||||
bool isbcc[MAXN]; // 标记节点是否已属于某个v-BCC
|
||||
|
||||
std::vector<std::vector<int>> bcc; // 存储所有找到的点双连通分量
|
||||
|
||||
void tarjan(int u, int parent) {
|
||||
dfn[u] = low[u] = ++ts;
|
||||
stk[++top] = u;
|
||||
|
||||
// 对于孤立点,若没有边,则tarjan函数会直接结束。
|
||||
// 我们将在main函数中处理这种情况。
|
||||
|
||||
for (int v : adj[u]) {
|
||||
// 在无向图中,(u,v)和(v,u)是同一条边,避免访问刚过来的边
|
||||
if (v == parent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!dfn[v]) { // v未被访问,是u在DFS树中的子节点
|
||||
tarjan(v, u);
|
||||
low[u] = std::min(low[u], low[v]);
|
||||
|
||||
// 关键判断:v及其子树无法到达u的祖先
|
||||
if (low[v] >= dfn[u]) {
|
||||
std::vector<int> curbcc;
|
||||
int node;
|
||||
// 从栈中弹出节点,直到v被弹出
|
||||
do {
|
||||
node = stk[top--];
|
||||
curbcc.push_back(node);
|
||||
isbcc[node] = true;
|
||||
} while (node != v);
|
||||
|
||||
// 割点u也属于这个v-BCC
|
||||
curbcc.push_back(u);
|
||||
isbcc[u] = true;
|
||||
|
||||
bcc.push_back(curbcc);
|
||||
}
|
||||
} else { // v已被访问,(u,v)是返祖边
|
||||
low[u] = std::min(low[u], dfn[v]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::ios_base::sync_with_stdio(false);
|
||||
std::cin.tie(nullptr);
|
||||
|
||||
std::cin >> n >> m;
|
||||
|
||||
for (int i = 0; i < m; ++i) {
|
||||
int u, v;
|
||||
std::cin >> u >> v;
|
||||
// 题目允许重边和自环。对于v-BCC,重边和一条边效果一样,自环可特殊处理
|
||||
// 此处我们正常建图,让tarjan处理
|
||||
if (u == v) continue; // v-BCC定义通常不考虑自环,但题目样例有,先忽略自环边,最后处理孤立点
|
||||
adj[u].push_back(v);
|
||||
adj[v].push_back(u);
|
||||
}
|
||||
|
||||
// 遍历所有节点,确保处理完所有连通分量
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
if (!dfn[i]) {
|
||||
// 如果一个节点是孤立的(或只与已访问过的部分相连),
|
||||
// tarjan调用后栈可能为空或只含自己。
|
||||
// 为了简化,我们只在tarjan内部处理连通的组件。
|
||||
tarjan(i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// 最后的清扫:处理所有未被分配到任何v-BCC的节点
|
||||
// 这些通常是孤立点,或者图中只有一个节点的情况,包括有自环的孤立点
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
if (!isbcc[i]) {
|
||||
bcc.push_back({i});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 输出结果
|
||||
std::cout << bcc.size() << "\n";
|
||||
for (const auto& ret : bcc) {
|
||||
std::cout << ret.size();
|
||||
for (int node : ret) {
|
||||
std::cout << " " << node;
|
||||
}
|
||||
std::cout << "\n";
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user