题解 [ARC092F] Two Faced Edges
link
题目大意
给一个
题解
首先我们给原图跑一边 tarjan 求出祂的 scc,对于边我们分情况讨论。
对于两端在同一个 scc 的边
对于两端不在同一个 scc 的边
可以发现,求
只有
把
那我们怎么办呢,我们可以再搜一个数组
下面是 chelsy 不知道可不可爱的代码(
#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=2e3, M=4e5;
int n, m, dfn[N], low[N], tim, u[M], v[M], cur[N];
int vis[N], stk[N], top, cnt, f[N][N], g[N][N];
vector<int> to[N];
void tarjan(int x) {
dfn[x]=low[x]=++tim;
vis[x]=1, stk[++top]=x;
for(int i=0; i<to[x].size(); ++i) {
int y=to[x][i];
if(vis[y]==2) continue;
if(!vis[y]) tarjan(y);
low[x]=min(low[x],low[y]);
}
if(dfn[x]==low[x]) {
++cnt; int p;
while(stk[top+1]!=x) {
p=stk[top--];
cur[p]=cnt, vis[p]=2;
}
}
}
void dfs(int x,int p) {
for(int i=0; i<to[x].size(); ++i) {
int y=to[x][i];
if(f[p][y]==-1) f[p][y]=f[p][x]+1, dfs(y,p);
}
}
void dfs2(int x,int p) {
for(int i=to[x].size()-1; i>=0; --i) {
int y=to[x][i];
if(g[p][y]==-1) g[p][y]=g[p][x]+1, dfs2(y,p);
}
}
signed main() {
scanf("%d%d", &n, &m);
for(int i=1; i<=m; ++i) {
scanf("%d%d", u+i, v+i);
to[u[i]].pb(v[i]);
}
for(int i=1; i<=n; ++i) if(!vis[i]) tarjan(i);
memset(f,-1,sizeof(f)), memset(g,-1,sizeof(g));
for(int i=1; i<=n; ++i) f[i][i]=0, dfs(i,i);
for(int i=1; i<=n; ++i) g[i][i]=0, dfs2(i,i);
for(int i=1; i<=m; ++i) {
bool t=(f[u[i]][v[i]]>1)|(g[u[i]][v[i]]>1);
if(t^(cur[u[i]]==cur[v[i]])) printf("diff\n");
else printf("same\n");
}
return 0;
}