ARC092F Two Faced Edges 题解
题目描述
给定 \(n\) 个点, \(m\) 条边的有向图,对每条边判断如果将其反向,强连通分量数量是否会改变。
数据范围
- \(2\le n\le 10^3,1\le m\le 2\cdot 10^5\) 。
时间限制 \(\texttt{5s}\) ,空间限制 \(\texttt{256MB}\) 。
模拟赛加强到 \(n\le 1.5\cdot 10^3,m\le 10^6\) 。
分析
对于 \(u\to v\) 的边,分情况讨论:
- 如果 \(u,v\) 原本在同一个强连通分量中,那么答案为
diff当且仅当将其删去后不存在 \(u\to v\) 的路径。 - 如果 \(u,v\) 原本不在同一个强连通分量中,那么答案为
diff当且仅当将其删去后存在 \(u\to v\) 的路径。
前一个条件是容易的,直接跑强连通分量即可。
对于第二个条件,枚举 \(u\) ,我们希望一次性统计所有 \(v\) 的答案。
记 \(u\) 的所有出边为 \(v_1,\cdots,v_k\) ,顺序遍历 \(v_i\) , bfs 标记每个点的最小访问时间,逆序再做一遍相同的事情。
对于 \(\forall1\le i\le k\) ,如果 \(v_i\) 存在一个标记不为自身,那么 \(u\to v\) 不是必经边。
至此我们获得了一个 \(\mathcal O(nm)\) 的做法,可以通过原题数据范围。
上述做法的复杂度瓶颈在于 bfs 要遍历整张图。
用 bitset 状压所有未被标记的点,由于 _Find_first 的时间复杂度为 \(\mathcal O(\frac n\omega+cnt_1)\) ,因此遍历整张图的代价为 \(\mathcal O(\frac{n^2}\omega)\) 。
算上外层枚举 \(u\) 的代价,时间复杂度 \(\mathcal O(\frac{n^3}\omega+m)\) 。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1005,maxm=2e5+5;
int m,n,cnt,num;
int u[maxm],v[maxm];
bool f[maxn][maxn];
bitset<maxn> cur,b[maxn];
int dfn[maxn],low[maxn];
int bel[maxn];
bool ins[maxn];
stack<int> st;
vector<int> g[maxn],vec[maxn];
void tarjan(int u)
{
dfn[u]=low[u]=++cnt,st.push(u),ins[u]=true;
for(auto v:g[u])
{
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(ins[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
num++;
int v;
do v=st.top(),st.pop(),bel[v]=num,ins[v]=false;
while(v!=u);
}
}
void solve(int x)
{
for(int op=0;op<=1;op++)
{
queue<int> q;
cur.set(),cur[x]=0;
reverse(g[x].begin(),g[x].end());
for(auto y:g[x])
{
f[x][y]|=!cur[y],cur[y]=0,q.push(y);
while(!q.empty())
{
int u=q.front();
q.pop();
auto now=b[u]&cur;
for(int i=now._Find_first();i!=now.size();i=now._Find_next(i)) cur[i]=0,q.push(i);
}
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&u[i],&v[i]);
b[u[i]][v[i]]=1,g[u[i]].push_back(v[i]);
}
for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
for(int i=1;i<=n;i++) solve(i);
for(int i=1;i<=m;i++) printf(f[u[i]][v[i]]^(bel[u[i]]==bel[v[i]])?"diff\n":"same\n");
return 0;
}
本文来自博客园,作者:peiwenjun,转载请注明原文链接:https://www.cnblogs.com/peiwenjun/p/17168830.html
浙公网安备 33010602011771号