WOJ 18 动态无向图

一开始我是不会写的,后来点开了题解:

无话可说……那就写吧……然而第一发跑成暴力分,后来加了一个优化:就是在询问里面提到过的边都不用再加了。

然后……然后就过了呀……

其实还有面向数据的编程的骚操作……既然卡过了那也没什么好说了。

以前的巨佬们Orz

Code:

#include <cstdio>
#include <cstring>
using namespace std;

const int N = 5005;
const int M = 8e5 + 5;

int n, m, qn, tot = 0, head[N], ans = 0;
int pCnt = 0, id[N], idCnt = 0, ufs[N], cnt[N][N];
bool ex[N][N], men[N][N], vis[N];

struct Edge {
    int to, nxt;
} e[M];

inline void add(int from, int to) {
    e[++tot].to = to;
    e[tot].nxt = head[from];
    head[from] = tot;
}

struct Pathway {
    int u, v;
} path[M];

struct Query {
    int type, u, v;
} q[M];

inline void read(int &X) {
    X = 0;
    char ch = 0;
    int op = 1;
    for(; ch > '9' || ch < '0'; ch = getchar())
        if(ch == '-') op = -1;
    for(; ch >= '0' && ch <= '9'; ch = getchar())
        X = (X << 3) + (X << 1) + ch - 48;
    X *= op; 
}

inline void init() {
    for(int i = 1; i <= n; i++) ufs[i] = i;
}

int find(int x) {
    return x == ufs[x] ? x : ufs[x] = find(ufs[x]);
}

inline void merge(int x, int y) {
    int fx = find(x), fy = find(y);
    if(ufs[fx] != fy) ufs[fx] = fy;
}

void dfs(int x) {
    vis[x] = 1;
    for(int i = head[x]; i; i = e[i].nxt) {
        int y = e[i].to;
        if(!ex[x][y]) continue;
        if(vis[y]) continue;
        dfs(y);
    }
}

inline void reCnt() {
    ans = 0;
    for(int i = 1; i <= idCnt; i++) vis[i] = 0;
    for(int i = 1; i <= idCnt; i++)
        if(!vis[i]) {
            ans++;
            dfs(i);
        }
}

inline void addEdge(int p) {
    int u = id[find(q[p].u)], v = id[find(q[p].v)];
    cnt[u][v]++, cnt[v][u]++;
    if(!ex[u][v]) {
        ex[u][v] = ex[v][u] = 1;
        add(u, v), add(v, u);
    }
    
//    reCnt();
} 

inline void delEdge(int p) {
    int u = id[find(q[p].u)], v = id[find(q[p].v)];
    cnt[u][v]--, cnt[v][u]--;
    if(!cnt[u][v] && !cnt[v][u]) 
        ex[u][v] = ex[v][u] = 0;    
    
//    reCnt();
}

inline void query(int p) {
    reCnt();
    printf("%d\n", ans);
}

int main() {
    read(n), read(m);
    for(int i = 1; i <= m; i++) 
        read(path[i].u), read(path[i].v);
    read(qn);
    for(int i = 1; i <= qn; i++) {
        char op[7];
        scanf("%s", op);
        if(op[0] == 'l') {
            q[i].type = 1, read(q[i].u), read(q[i].v);
            men[q[i].u][q[i].v] = men[q[i].v][q[i].u] = 1;
        }    
        if(op[0] == 'c') {
            q[i].type = 2;
            read(q[i].u), read(q[i].v);
            men[q[i].u][q[i].v] = men[q[i].v][q[i].u] = 1;
        }    
        if(op[0] == 'q') q[i].type = 3;
    } 
    
    init();
    for(int i = 1; i <= m; i++) {
        if(men[path[i].u][path[i].v]) continue;
        merge(path[i].u, path[i].v);
    }
    for(int i = 1; i <= n; i++) {
        int nowf = find(i);
        if(!vis[nowf]) vis[nowf] = 1, id[nowf] = ++idCnt;
    }
    
/*    for(int i = 1; i <= n; i++)
        printf("%d ", id[find(i)]);
    printf("\n");   */
    
    for(int i = 1; i <= m; i++) {
        if(!men[path[i].u][path[i].v]) continue;
        int x = id[find(path[i].u)], y = id[find(path[i].v)];
        add(x, y), add(y, x);
        ex[x][y] = ex[y][x] = 1;
        cnt[x][y]++, cnt[y][x]++;
    }
    
//    reCnt();
    for(int i = 1; i <= qn; i++) {
        if(q[i].type == 1) addEdge(i);
        if(q[i].type == 2) delEdge(i);
        if(q[i].type == 3) query(i);
    }
    
    return 0;
}
View Code

 

posted @ 2018-08-17 19:27  CzxingcHen  阅读(292)  评论(0编辑  收藏  举报