Dynamic Graph,一道图论题

题目链接:https://icpc-camp-cdn.b0.upaiyun.com/permanent/problems/sichuan-2017.pdf

题意简述:给你一个有向无环图,可以把图上的点涂成白色或黑色(初始都是白点),问起点到终点存在路径都是白点的点对有多少个?

分析:首先点数只有300,预计复杂度为O(N^2*q),DFS加bitset优化可以过就不讲了。
官方题解是这样说的:
可以 O(n^2) 维护 f(x, y) 表示从 x, y 的路径条数。例如删掉点 v,就是 f(x, y) 减去 f(x, v) × f(v, y).之后就可以通过 f(x, y) > 0 来判断 x 到 y 是否可达了。
但有几点需要注意,

  1. 需要O(n^3)构造出路径条数的矩阵,代码如下。
        for(int k=1; k<=n; ++k)
            for(int i=1; i<=n; ++i)
                for(int j=1; j<=n; ++j)
                   a[i][j] += a[i][k]*a[k][j];  
  1. 删点比较简单,但还原点有些难度,首先边的信息不能丢了,然后还原出f(v,y)和f(x,v),接着再还原f(x,y)
    代码如下
void del(int u) {
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n; ++j)
            a[i][j] -= a[i][u]*a[u][j];
    for(int i=1; i<=n; ++i)
        a[i][u] = a[u][i] = 0;
}
void add(int u) {
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n; ++j)
            if(color[i]==White&&color[j]==White) {
                a[u][i] += e[u][j]*a[j][i];
                a[i][u] += a[i][j]*e[j][u];
            }
    for(int i=1; i<=n; ++i)
        if(color[i]==White) {
            a[u][i] += e[u][i];
            a[i][u] += e[i][u];
        }
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n; ++j)
            if(color[i]==White&&color[j]==White)
                a[i][j] += a[i][u]*a[u][j];
}

你可能感兴趣的:(Dynamic Graph,一道图论题)