AT3945 [ARC092D] Two Faced Edges

https://www.luogu.com.cn/problem/AT3945

考虑 u − > v u->v u>v这条边对答案的影响

  • 如果图中存在 v − > u v->u v>u的路径,那么肯定会使答案-1
  • 如果删掉这条边后,图中还存在 u − > v u->v u>v的路径,那么会使答案+1

所以上面两个条件有且仅有一个满足时,联通块数会改变

对于第一种,直接暴力跑即可

对于第二种,可以枚举 u u u,然后把边表正反都跑一遍,看看通过不同的边,可不可以到同一个点(染色处理)

可以参考代码

code:

#include<bits/stdc++.h>
#define N 1005
using namespace std;
struct E {
    int u, v;
} e[N * N];
int n, m, ok[N][N], okk[N][N], vis[N], col[N], coll[N];
vector<int> g[N];
void dfs(int u, int s) {
    ok[s][u] = 1;
    for(int i = 0; i < g[u].size(); i ++) {
        int v = g[u][i];
        if(!ok[s][v]) dfs(v, s);
    }
}
void dfss(int u, int o) {
    col[u] = o; vis[u] = 1;
    for(int i = 0; i < g[u].size(); i ++) {
        int v = g[u][i];
        if(!vis[v]) {
            dfss(v, o);
        }
    }
}

void dfsss(int u, int o) {
    coll[u] = o;  vis[u] = 1;
    for(int i = 0; i < g[u].size(); i ++) {
        int v = g[u][i];
        if(!vis[v]) {
            dfsss(v, o);
        }
    }
}
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i ++) {
        scanf("%d%d", &e[i].u, &e[i].v);
        g[e[i].u].push_back(e[i].v);
    }
    for(int i = 1; i <= n; i ++) dfs(i, i);
    for(int u = 1; u <= n; u ++) {
        memset(vis, 0, sizeof vis);
        memset(col, 0, sizeof col);
        memset(coll, 0, sizeof coll);vis[u] = 1;
        for(int i = 0; i < g[u].size(); i ++) {
            int v = g[u][i];
            if(!vis[v]) dfss(v, v);
        }
        memset(vis, 0, sizeof vis); vis[u] = 1;
        for(int i = g[u].size() - 1; i >= 0; i --) {
            int v = g[u][i];
            if(!vis[v]) dfsss(v, v);
        }
        for(int v = 1; v <= n; v ++) if(col[v] != coll[v]) okk[u][v] = 1;
      /*  if(u == 3) {
            for(int i = 1; i <= n; i ++) printf("%d ", col[i]); printf("\n");
            for(int i = 1; i <= n; i ++) printf("%d ", coll[i]); printf("\n");
        }*/
    }
    for(int i = 1; i <= m; i ++) {
        int u = e[i].u, v = e[i].v;
        if(ok[v][u] ^ okk[u][v]) printf("diff\n");
        else printf("same\n");
    }
    return 0;
}
posted @ 2021-10-12 07:10  lahlah  阅读(30)  评论(0编辑  收藏  举报