标签:Tarjan int Bertown back push dfn low roads size
[CF118E] Bertown roads - Tarjan
Description
有n个交汇点和m条双向道路,一个人可以凭借现有的通道从一个点到达另一个点。确定这样一种方案,使每条道路改为单向行驶,但仍满足能够从任意一个点到达另一任意点的要求
Solution
关键是把图做成若干个环,而无解当且仅当图中有桥
因此我们先用 TARJAN 判断是否有桥,如果没有,构造解法输出,只需要一个不走重复边的 DFS 即可
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
int n, m;
vector<int> g[N], b[N], inv[N];
int low[N], dfn[N], ind, vis[N];
int flag_bridge;
void make(int p, int q)
{
inv[p].push_back(g[q].size());
inv[q].push_back(g[p].size());
g[p].push_back(q);
g[q].push_back(p);
b[p].push_back(0);
b[q].push_back(0);
}
void tarjan(int p, int from)
{
low[p] = dfn[p] = ++ind;
for (int i = 0; i < g[p].size(); i++)
{
int q = g[p][i];
if (q == from)
continue;
if (dfn[q] == 0)
{
tarjan(q, p);
low[p] = min(low[p], low[q]);
}
else
{
low[p] = min(low[p], dfn[q]);
}
if (low[q] > dfn[p])
flag_bridge = 1;
}
}
void print(int p)
{
vis[p] = 1;
for (int i = 0; i < g[p].size(); i++)
{
int q = g[p][i];
if (b[p][i])
continue;
b[p][i] = b[q][inv[p][i]] = 1;
if (!vis[q])
print(q);
cout << p << " " << q << endl;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int u, v;
cin >> u >> v;
make(u, v);
}
tarjan(1, 0);
if (flag_bridge)
{
cout << 0 << endl;
}
else
{
print(1);
}
}
标签:Tarjan,int,Bertown,back,push,dfn,low,roads,size 来源: https://www.cnblogs.com/mollnn/p/14613084.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。