Tree(HDOJ-2682)

今天還是複習圖論。
一道最小生成樹的題目,題目其實不難。
但一開始邊的數目用的是MAXN*MAXN/2,MLE了一次,換vector之後不斷地WA……結果上來看是因爲沒有用素數篩法,之前用的是這樣的一個單獨判斷一個數是否是素數的辦法,也是之前一直用的,不知道爲什麼這次不行。

bool check(int x) {
    if (x == 2 || x == 3) return true;
    if (x % 6 != 5 && x % 6 != 1) return false;
    for (int i = 5; i < sqrt(x); i += 6)
        if (x % i == 0 || x % (i + 2) == 0) return false;
    return true;
}

之後換用素數篩法之後就AC了……真是見鬼

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <list>
#include <cmath>
#include <algorithm>
#define MST(a, b) memset(a, b, sizeof(a))
using namespace std;
const int MAXN = 620;
const int MAXP = 2000000 + 50;
typedef long long ll;
struct edge {
    int start, end, cur;
} ;
int t, n, value[MAXN], fa[MAXN];
bool prime[MAXP];
vector <edge> e;
void pre() {
    MST(prime, 0);
    prime[1] = 1;
    for (int i = 2; i <= sqrt(MAXP); i++) {
        if (prime[i]) continue;
        for (int j = i * i; j < MAXP; j += i)
            prime[j] = 1;
    }
}
void init() {
    for (int i = 1; i <= n; i++) fa[i] = i;
    e.clear();
    MST(value, 0);
}
int find_fa(int x) {
    return fa[x] == x ? fa[x] : fa[x] = find_fa(fa[x]);
}
void merge_fa(int x, int y) {
    int fx = find_fa(x), fy = find_fa(y);
    if (fx != fy) fa[fy]= fx;
}
bool cmp(edge a, edge b) {
    return a.cur < b.cur;
}
int kruskal() {
    int res = 0, sum = 0;
    sort(e.begin(), e.end(), cmp);
    for (int i = 0; i < e.size(); i++) {
        if (find_fa(e[i].start) != find_fa(e[i].end)) {
            merge_fa(e[i].start, e[i].end);
            res += e[i].cur;
            sum++;
        }
    }
    if (sum < n - 1) return -1;
    return res;
}
int main() {
    pre();
    scanf("%d", &t);
    while (t--) {
        scanf("%d", &n);
        init();
        for (int i = 1; i <= n; i++) scanf("%d", &value[i]);
        for (int i = 1; i <= n; i++)
            for (int j = i + 1; j <= n; j++)
                if (!prime[value[i]] || !prime[value[j]] || !prime[value[i] + value[j]]) {
                    edge tmpe;
                    tmpe.start = i;
                    tmpe.end = j;
                    tmpe.cur = min(min(value[i], value[j]), abs(value[i] - value[j]));
                    e.push_back(tmpe);
                }
        printf("%d\n", kruskal());
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章