hihoCoder1097 暴力 + 优先队列优化

hihoCoder1097

暴力法 ( O ( l o g ( n 2 ) O(log(n^2) O(log(n2)

#include <iostream>
#include <cstring>
using namespace std;

const int INF = 0x3f3f3f3f;
bool st[10005];
int dist[10005];
int g[1010][10005];

int n;
int prim() {
    int res = 0;
    for (int i = 1; i <= n; i++) {
        dist[i] = INF;
        st[i] = false;
    }
    dist[1] = 0;
    for (int i = 1; i <= n; i++) {
        int id = -1, min_dist = INF;
        for (int j = 1; j <= n; j++) {
            if (!st[j] && dist[j] < min_dist) {
                id = j;
                min_dist = dist[j];
            }
        }
        st[id] = true;
        res += dist[id];
        //刷新辅助数组
        for (int j = 1; j <= n; j++) {
            if (!st[j] && dist[j] > g[id][j]) {
                dist[j] = g[id][j];
                //dist[j] = min(dist[j], g[id][j]);
            }
        }
    }
    return res;
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) {
            cin >> g[i][j];
        }
    }
    memset(dist, 0, sizeof dist);
    cout << prim() << endl;
    return 0;
}


优先队列(堆优化) O ( ( n + m ) l o g m ) O((n + m)logm) O((n+m)logm)

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

const int maxn = 1005;
const int INF = 0x7fffffff;
int vis[maxn];//判断是否标记
int p[maxn][maxn];//存图
int n, m, ans = 0;
struct edge { //保存边的情况,to为通往的边
    int to;
    int v; //权值
    friend bool operator < (const edge &x, const edge &y) {
        return x.v > y.v; //优先队列即最小堆
    }
}now;

priority_queue <edge> q;
void prim (int key) {
    vis[key] = 1;  //标记起始点
    while (!q.empty()) q.pop();
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n; j++) { //记入新加入点的情况
            if (!vis[j]) { //没标记过的点就加入
                now.to = j;
                now.v = p[key][j];
                //printf("j=%d,p[%d][%d]=%d\n",j,key,j,p[key][j]);
                q.push(now);
            }
        }
        while (!q.empty() && vis[q.top().to]) {
            q.pop();
        }
        if (q.empty()) break;
        now = q.top();
        key = now.to;
        ans += now.v; //累加最小边的权值
        vis[key] = 1;
        q.pop();
    }
}

int main() {
    //cin >> n;
    scanf ("%d", &n);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> p[i][j];
        }
    }
    memset(vis, 0, sizeof vis);
    prim(0);
    cout << ans << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44123547/article/details/106117012
今日推荐