码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj3714 [PA2014]Kuglarz 最小生成树

时间:2018-10-12 17:01:59      阅读:173      评论:0      收藏:0      [点我收藏+]

标签:double   gis   class   code   namespace   inline   pair   nbsp   zoj   

题面:

魔术师的桌子上有$n$个杯子排成一行,编号为$1,2,…,n$,其中某些杯子底下藏有一个小球,如果你准确地猜出是哪些杯子,你就可以获得奖品。

花费$c_ij$元,魔术师就会告诉你杯子$i,i+1,…,j$底下藏有球的总数的奇偶性。

采取最优的询问策略,你至少需要花费多少元,才能保证猜出哪些杯子底下藏着球?

 

我们可以把前$i$个杯子的球的奇偶关系看做一个点$S[i]$

那么,原题相当于最小生成树

使用$prim$算法可以做到$O(n^2)$

 

#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
    #define re register
    #define de double
    #define le long double
    #define ri register int
    #define ll long long
    #define sh short
    #define pii pair<int, int>
    #define mp make_pair
    #define pb push_back
    #define tpr template <typename ra>
    #define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
    #define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)    
    extern inline char gc() {
        static char RR[23456], *S = RR + 23333, *T = RR + 23333;
        if(S == T) fread(RR, 1, 23333, stdin), S = RR;
        return *S ++;
    }
    inline int read() {
        int p = 0, w = 1; char c = gc();
        while(c > 9 || c < 0) { if(c == -) w = -1; c = gc(); }
        while(c >= 0 && c <= 9) p = p * 10 + c - 0, c = gc();
        return p * w;
    }
    int wr[50], rw;
    #define pc(iw) putchar(iw)
    tpr inline void write(ra o, char c = \n) {
        if(!o) pc(0);
        if(o < 0) o = -o, pc(-);
        while(o) wr[++ rw] = o % 10, o /= 10;
        while(rw) pc(wr[rw --] + 0);
        pc(c);
    }
    tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; }
    tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; } 
    tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, 1 : 0; }
    tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, 1 : 0; }
}
using namespace std;
using namespace remoon;

#define sid 2005

int n;
ll ans;
int vis[sid], low[sid], who[sid];
int w[sid][sid];

inline void MST() {
    vis[1] = 1;
    rep(i, 1, n + 1) low[i] = 1e9 + 5;
    rep(i, 2, n + 1) 
    if(!vis[i] && ckmin(low[i], w[1][i])) who[i] = 1;
    rep(t, 1, n) {
        int nv = -1, dis = 1e9;
        rep(i, 1, n + 1)
        if(!vis[i] && ckmin(dis, low[i])) nv = i;
        ans += dis; vis[nv] = 1;
        rep(i, 1, n + 1)
        if(!vis[i] && ckmin(low[i], w[nv][i])) who[i] = nv;
    }
    write(ans);
}

int main() {
    n = read();
    memset(w, 127, sizeof(w));
    rep(i, 1, n) rep(j, i, n) 
    w[j + 1][i] = w[i][j + 1] = read();
    MST();
    return 0;
}

 

bzoj3714 [PA2014]Kuglarz 最小生成树

标签:double   gis   class   code   namespace   inline   pair   nbsp   zoj   

原文地址:https://www.cnblogs.com/reverymoon/p/9778901.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!