Algorithm: bipartite graph maximum independent set

Maximum Independent Set bipartite graph, but also a very classic problem of a bipartite graph.

example

Original examples

Title Description
Given a bipartite graph, each represent a number of nodes n, m, side is e, the maximum number of seek bipartite graph matching.

Input format
of the first row, n, m, e.
Second to (e + 1) lines of two positive integers u, v, represents u, v have an even edge.

Output Format

The first row, point bipartite graph maximum independent set.
The second line, between the left point set independently of the output one of the greatest diversity scheme, the element by element separated by a space.
The third line, between the right point set independently of the output one of the greatest diversity scheme, the element by element separated by a space.

Sample input and output

Entry

4 4 7
1 1
1 3
2 2
2 3
2 4
3 2
4 2

Export

5
3 4
1 3 4

Description / Tips
1 <= n, m <= 1000, 1 <= e <= n * m.

Bipartite graph maximum independent set

Let me talk about what is the largest independent set of bipartite graphs: that is, as many bipartite graph selected point, but have to ensure that there is no edge between any two selected points. For example, as shown below.

Here Insert Picture Description

Red dot is the largest independent centralized point, we can see that these points are not connected between any two sides.

In fact, the largest independent set of points is that all points covered threw minimum point, then this is why?

Because the point of the minimum point coverage covers all edges, that is, any one edge has a point in covering the minimum point, so long as these points still to go, each side will only have an endpoint, and naturally it is independent set up, but because the cover is removed the minimum point, it is the largest independent natural set up.

So to conclude: = maximum independent set of all points - Minimum Vertex Cover

The code word with minimum point code covering almost the same, about the same time complexity: O (n * m).

Code

# include <cstdio>
# include <algorithm>
# include <cmath>
# include <cstring>
# include <vector>

using namespace std;

const int N_MAX = 1000, E_MAX = 1000000;

struct Edge
{
    int to, next;
};

int n, m, e;
vector <int> g[N_MAX + 10];

int opp[N_MAX + 10];
bool vis[N_MAX + 10];

bool vx[N_MAX + 10], vy[N_MAX + 10];

void addEdge(int x, int y)
{
    g[x].push_back(y);
}

bool find(int x)
{
    if (vis[x]) return false;
    vis[x] = true;
    for (int i = 0; i < (int) g[x].size(); i++) {
        int y = g[x][i];
        if (opp[y] == 0 || find(opp[y])) {
            opp[y] = x;
            return true;
        }
    }
    return false;
}

void mark(int x)
{
    if (vx[x]) return;
    vx[x] = true;
    for (int i = 0; i < (int) g[x].size(); i++) {
        int y = g[x][i];
        if (opp[y] && !vy[y]) {
            vy[y] = true;
            mark(opp[y]);
        }
    }
}

int hungary()
{
    memset(opp, 0, sizeof(opp));
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        memset(vis, false, sizeof(vis));
        ans += find(i);
    }
    return ans;
}

int maxIndSet()
{
    int ans = hungary();
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= m; i++)
        vis[opp[i]] = true;
    memset(vx, false, sizeof(vx));
    memset(vy, false, sizeof(vy));
    for (int i = 1; i <= n; i++)
        if (!vis[i]) mark(i);
    return n + m - ans;
}

int main()
{
    scanf("%d%d%d", &n, &m, &e);
    for (int i = 1; i <= e; i++) {
        int x, y;
        scanf("%d%d", &x, &y);
        addEdge(x, y);
    }
    printf("%d\n", maxIndSet());
    for (int i = 1; i <= n; i++)
        if (vx[i]) printf("%d ", i);
    puts("");
    for (int i = 1; i <= m; i++)
        if (!vy[i]) printf("%d ", i);
    puts("");
    return 0;
}

Guess you like

Origin www.cnblogs.com/000zwx000/p/12516388.html