Codeforces Round #500 (Div. 2) D. Chemical table (思维+图论)

版权声明:希望能在自己成长的道路上帮到更多的人,欢迎各位评论交流 https://blog.csdn.net/yiqzq/article/details/82467126

原题地址:http://codeforces.com/contest/1013/problem/D

题意:给你一个 n m 的矩形,一开始有 q 个格子上被标记。对于任意两行两列,如果交汇的四个格子中有三个被标记,那么第4个会被自动标记。问你至少需要手动标记几个格子,使得整个矩形内的格子都被标记。

思路:这题一开始真的想不到可以用二分图建图然后求强连通分量来做.

具体解释可以看这里https://blog.csdn.net/qq_39984146/article/details/81321885

ac代码:

#include <bits/stdc++.h>
#define eps 1e-8
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 4e5 + 5;
const int mod = 1e9 + 7;
int n, m, q;
struct node {
    int v, nxt;
} e[maxn << 1];
int tot, head[maxn];
void init_head() {
    tot = 0;
    CLR(head, -1);
}
void add_edge(int u, int v) {
    e[tot].v = v;
    e[tot].nxt = head[u];
    head[u] = tot++;
}
int cnt;
int vis[maxn];
void dfs(int u) {
    vis[u] = 1;
    for (int i = head[u]; ~i; i = e[i].nxt) {
        int  v = e[i].v;
        if (vis[v]) continue;
        dfs(v);
    }
}
int main() {
    cnt = 0;
    CLR(vis, 0);
    scanf("%d%d%d", &n, &m, &q);
    init_head();
    for (int i = 1; i <= q; i++) {
        int u, v;
        scanf("%d%d", &u, &v);
        add_edge(u, n + v);
        add_edge(n + v, u);
    }
    for (int i = 1; i <= n + m; i++) {
        if (vis[i] == 0) {
            cnt++;
            dfs(i);
        }
    }
    printf("%d\n", cnt - 1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yiqzq/article/details/82467126