FZU 2194 星系碰撞(二分图匹配)

来源:互联网 发布:js div显示隐藏 编辑:程序博客网 时间:2024/04/30 09:31

题目链接:http://acm.fzu.edu.cn/problem.php?pid=2194


思路:对于所有点将与其距离 <= 5 的点连边,然后跑二分图匹配,最后算出最大独立集,这题数据量比较大,用的是Hopcroft-Carp算法,复杂度O(sqrt(n) * E),另外使用map时要使用内置的pair类型和find函数,否则会T。。。


#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <utility>#include <cmath>#include <queue>#include <set>#include <map>#include <climits>#include <functional>#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;const int MAXN = 50010;const int INF = INT_MAX - 1;vector <int> G[MAXN];int uN;int Mx[MAXN], My[MAXN];int dx[MAXN], dy[MAXN];int dis;bool used[MAXN];struct node{    int x, y;} a[MAXN];typedef pair <int, int> P;bool SearchP(){    queue <int> Q;    dis = INF;    memset(dx, -1, sizeof(dx));    memset(dy, -1, sizeof(dy));    for (int i = 0 ; i < uN; i++)        if (Mx[i] == -1)        {   Q.push(i);            dx[i] = 0;        }    while (!Q.empty())    {        int u = Q.front();        Q.pop();        if (dx[u] > dis)break;        int sz = G[u].size();        for (int i = 0; i < sz; i++)        {            int v = G[u][i];            if (dy[v] == -1)            {                dy[v] = dx[u] + 1;                if (My[v] == -1)dis = dy[v];                else                {                    dx[My[v]] = dy[v] + 1;                    Q.push(My[v]);                }            }        }    }    return dis != INF;}bool DFS(int u){    int sz = G[u].size();    for (int i = 0; i < sz; i++)    {        int v = G[u][i];        if (!used[v] && dy[v] == dx[u] + 1)        {            used[v] = true;            if (My[v] != -1 && dy[v] == dis)continue;            if (My[v] == -1 || DFS(My[v]))            {                My[v] = u;                Mx[u] = v;                return true;            }        }    }    return false;}int MaxMatch(){    int res = 0;    memset(Mx, -1, sizeof(Mx));    memset(My, -1, sizeof(My));    while (SearchP())    {        memset(used, false, sizeof(used));        for (int i = 0; i < uN; i++)            if (Mx[i] == -1 && DFS(i))                res++;    }    return res;}map <P, int> ma;void init(int n){    ma.clear();    for (int i = 0; i <= n; i++)        G[i].clear();}int main(){    int n;    while (~scanf("%d", &n))    {        init(n);        for (int i = 0; i < n; i++)        {            scanf("%d%d", &a[i].x, &a[i].y);            ma[P(a[i].x, a[i].y)] = i + 1;        }        uN = n;        map <P, int> ::iterator it;        for (int i = 0; i < n; i++)        {            for (int j = -5; j <= 5; j++)            {                for (int k = -5; k <= 5; k++)                {                    if (j * j + k * k > 25) continue;                    if (j == 0 && k == 0) continue;                    P nxt;                    nxt.first = a[i].x + j, nxt.second = a[i].y + k;                    it = ma.find(nxt);                    if (it->second)                        G[i].push_back(it->second - 1);                }            }        }        int res = MaxMatch() / 2;        if (res == n)            puts("-1");        else            printf("%d\n", n - res);    }    return 0;}


0 0