UVALive

来源:互联网 发布:网络订单之小鸭子 编辑:程序博客网 时间:2024/06/10 09:25

一个点由半径和斜率确定,判重后将半径和斜率之间建一条边跑匈牙利即可

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#include <vector>#include <map>using namespace std;const int INF = 0x3f3f3f3f;const int maxn = 2 * 1e4 + 10;int tot, head[maxn];struct Edge {    int v, next;    Edge(int x = 0, int y = 0) : v(x), next(y) {}}edge[maxn];void init() {    tot = 0;    memset(head, -1, sizeof(head));}void addedge(int u, int v) {    ++tot;    edge[tot].v = v; edge[tot].next = head[u];    head[u] = tot;}int n, cnt1, cnt2;map<int, int> m1;map<double, int> m2;int from[maxn];bool vis[maxn];bool match(int u) {    for (int i = head[u]; i != -1; i = edge[i].next) {        int v = edge[i].v;        if (!vis[v]) {            vis[v] = true;            if (from[v] == -1 || match(from[v])) {                from[v] = u;                return true;            }        }    }    return false;}int hungary() {    int ans = 0;    memset(from, -1, sizeof(from));    for (int i = 1; i <= cnt1; i++) {        memset(vis, false, sizeof(vis));        if (match(i)) ++ans;    }    return ans;}int main() {    int T, r, a, b; scanf("%d", &T);    for (int kase = 1; kase <= T; kase++) {        scanf("%d", &n);        init();        cnt1 = 0, cnt2 = 0;        m1.clear();        m2.clear();        for (int j = 1; j <= n; j++) {            scanf("%d %d %d", &r, &a, &b);            if (!m1[r]) m1[r] = ++cnt1;            double k = 1.0 * a / b;            if (!m2[k]) m2[k] = ++cnt2;            addedge(m1[r], m2[k]);        }        printf("%d\n", hungary());    }    return 0;}


原创粉丝点击