Equivalent Sets HDU - 3836 (Tarjan)

Posted h-riven

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Equivalent Sets HDU - 3836 (Tarjan)相关的知识,希望对你有一定的参考价值。

题目说给出一些子集,如果A是B的子集,B是A的子集,那么A和B就是相等的,然后给出n个集合m个关系,m个关系表示u是v的子集,问你最小再添加多少个关系可以让这n个集合都是相等的

如果这n个几个都是互相相等的,那么就等于是这n个集合看成点以后,构成的图是一个强连通图,那么就是说在加多少边让这个图变成强联通图。

先缩点然后做判断

1,如果原本的图本来就是强联通的,那么答案就是0

2.如果原本的图不是强联通的,那就去判断缩完以后的点的入度和出度,取入度为0的和出度为0的点数的最大值,就是最小需要加的边

技术分享图片
#include<map>
#include<set>
#include<ctime>
#include<cmath>
#include<stack>
#include<queue>
#include<string>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define lowbit(x) (x & (-x))

typedef unsigned long long int ull;
typedef long long int ll;
const double pi = 4.0*atan(1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 20005;
const int maxm = 50005;
const int mod = 10007;
using namespace std;

int n, m, tol, T;
int cnt, sz, top;
struct Node {
    int u, v;
    int next;
};
Node node[maxm];
int head[maxn];
int dfn[maxn];
int low[maxn];
int ind[maxn];
int oud[maxn];
int sta[maxn];
int point[maxn];
bool vis[maxn];

void init() {
    tol = cnt = top = sz = 0;
    memset(dfn, 0, sizeof dfn);
    memset(low, 0, sizeof low);
    memset(ind, 0, sizeof ind);
    memset(oud, 0, sizeof oud);
    memset(vis, 0, sizeof vis);
    memset(head, -1, sizeof head);
    memset(point, 0, sizeof point);
}

void addnode(int u, int v) {
    node[tol].u = u;
    node[tol].v = v;
    node[tol].next = head[u];
    head[u] = tol++;
}

void dfs(int u) {
    int v;
    dfn[u] = low[u] = ++cnt;
    sta[sz++] = u;
    vis[u] = true;
    for(int i=head[u]; ~i; i=node[i].next) {
        v = node[i].v;
        if(!dfn[v]) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if(vis[v]) {
            low[u] = min(low[u], dfn[v]);
        }
    }
    if(dfn[u] == low[u]) {
        top++;
        do {
            v = sta[--sz];
            point[v] = top;
            vis[v] = false;
        } while(v != u);
    }
}

void tarjan() {
    for(int u=1; u<=n; u++) {
        if(!dfn[u])    dfs(u);
    }
}

void solve() {
    for(int u=1; u<=n; u++) {
        for(int i=head[u]; ~i; i=node[i].next) {
            int v = node[i].v;
            if(point[u] != point[v]) {
                ind[point[v]]++;
                oud[point[u]]++;
            }
        }
    }
}

int main() {
    while(~scanf("%d%d", &n, &m)) {
        init();
        int u, v;
        for(int i=1; i<=m; i++) {
            scanf("%d%d", &u, &v);
            addnode(u, v);
        }
        tarjan();
//        for(int i=1; i<=n; i++)    printf("!!!!%d %d
", i, point[i]);
        if(top == 1) {
            printf("0
");
            continue;
        }
        solve();
        int ans1=0, ans2=0;
        memset(vis, 0, sizeof vis);
        for(int i=1; i<=top; i++) {
            if(ind[i] == 0)    ans1++;
            if(oud[i] == 0)    ans2++;
        }
        printf("%d
", max(ans1, ans2));
    }
    return 0;
}
View Code

 

以上是关于Equivalent Sets HDU - 3836 (Tarjan)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 3836 Equivalent Sets trajan缩点

hdu 3836 Equivalent Sets(强连通分量--加边)

HDU 3836 Equivalent Sets(强连通分量)

hdu 3836 Equivalent Sets

HDU - 3836 Equivalent Sets (强连通分量+DAG)

Equivalent Sets HDU - 3836 (Tarjan)