1. 程式人生 > >kuangbin帶你飛 專題八 生成樹

kuangbin帶你飛 專題八 生成樹

HDU 4081(次小生成樹)

題意:這題是給你n個點座標,m條邊,然後讓你連成一棵生成樹,可以把其中一條邊的權值變為0,然後求這條邊兩端點的權值之和/(生成樹權值-這條邊權)最大值

題解:這得列舉刪除每一條邊啊,然後求含有這條邊的最小生成樹

看了題解之後才明白這是求次小生成樹(用prim演算法),先求MST,並且記錄下哪條邊是MST中的,然後列舉MST中的邊(p1+p2)/(MST-edge)

如果這條邊不是MST中的,但是要求含有這條邊的MST,那麼將這條邊連入MST中,去掉可以去掉的邊種權值最大的,不就是含有這條邊的MST麼

如何來求這個可以去掉的權值最大的邊,如果代替他的邊,連線a,b,那麼a,b原本就是一棵樹上的,就找a,b之間的最大邊,記為path[a][b]

path[a][b]=max(path[a][pre[b]],edge[pre[b]][a])

#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;
#define   MAX       1000+5
#define   MAXN      100000+5
#define   lson      l,m,rt<<1
#define   rson      m+1,r,rt<<1|1
#define   lrt       rt<<1
#define   rrt       rt<<1|1
#define   mid       int m=(r+l)>>1
#define   LL        long long
#define   ull       unsigned long long
#define   mem0(x)   memset(x,0,sizeof(x))
#define   mem1(x)   memset(x,-1,sizeof(x))
#define   meminf(x) memset(x,INF,sizeof(x))
#define   lowbit(x) (x&-x)

const int    mod   = 1000000007;
const int    prime = 999983;
const int    INF   = 0x3f3f3f3f;
const int    INFF  = 1e9;
const double pi    = 3.141592653589793;
const double inf   = 1e18;
const double eps   = 1e-10;

//讀入外掛
inline int read_int(){
    int ret=0;
    char tmp;
    while(!isdigit(tmp=getchar()));
    do{
        ret=(ret<<3)+(ret<<1)+tmp-'0';
    }
    while(isdigit(tmp=getchar()));
    return ret;
}

struct Node{
    double x,y,p;
}node[MAX];
double edge[MAX][MAX];
double path[MAX][MAX];
double dis[MAX];
int vis[MAX];
int use[MAX][MAX];
int pre[MAX];
int n;

double prim(){
    mem0(path);
    mem0(vis);
    mem0(use);
    vis[1]=1;
    dis[0]=INF;
    double ans=0;
    for(int i=1;i<=n;i++){
        dis[i]=edge[1][i];
        pre[i]=1;
    }
    while(1){//prim演算法
        int x=0;
        for(int i=1;i<=n;i++){
            if(!vis[i]&&dis[i]<dis[x]) x=i;
        }
        if(!x) break;
        vis[x]=1;
        ans+=dis[x];
        use[pre[x]][x]=use[x][pre[x]]=1;
        for(int i=1;i<=n;i++){
            if(!vis[i]&&dis[i]>edge[x][i]){//計算MST
                dis[i]=edge[x][i];
                pre[i]=x;
            }
            else if(vis[i]&&i!=x){//計算x到前面每個點的路中的權值最大的邊
                path[i][x]=path[x][i]=max(path[i][pre[x]],edge[pre[x]][x]);
            }
        }
    }
    return ans;
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        mem0(edge);
        for(int i=1;i<=n;i++){
            double a,b,c;
            scanf("%lf%lf%lf",&a,&b,&c);
            node[i]=(Node){a,b,c};
            for(int j=1;j<i;j++){
                double r=node[i].x-node[j].x;
                double s=node[i].y-node[j].y;
                double diss=sqrt(r*r+s*s);
                edge[i][j]=edge[j][i]=diss;
            }
        }
        double ans=prim();
        double r=0;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(i==j) continue;
                if(use[i][j]){
                    r=max(r,(node[i].p+node[j].p)/(ans-edge[i][j]));//MST中的邊
                }
                else {
                    r=max(r,(node[i].p+node[j].p)/(ans-path[i][j]));//不是MST中的邊
                }
            }
        }
        printf("%.2f\n",r);
    }
    return 0;
}
poj 3164(最小樹形圖)

題意:給一個DAG,求DAG的MST

題解:這題一開始以為很水u,結果WA

然後看了題解,最小樹形圖-朱劉演算法(還是挺難的)



相關推薦

kuangbin 專題 成樹

HDU 4081(次小生成樹) 題意:這題是給你n個點座標,m條邊,然後讓你連成一棵生成樹,可以把其中一條邊的權值變為0,然後求這條邊兩端點的權值之和/(生成樹權值-這條邊權)最大值 題解:這得列舉刪除每一條邊啊,然後求含有這條邊的最小生成樹 看了題解之後才明白這是求次小生

[kuangbin]專題 成樹 題解彙總

本來準備省賽和其他的比賽先不打算做kuangbin專題了,不過我朋友AK了最小生成樹專題,問我繼續怎麼練。既然都練了最小生成樹,不如把後面的那個生成樹專題也啃了吧。然後clone生成樹專題,花了5天懟完。主要是中間一堆作業要懟,耽誤了很多時間。我把我的題解和程式碼都放到了Gi

[kuangbin]專題六 最小生成樹

You are a member of the space station engineering team, and are assigned a task in the construction process of the station. You are expected to write a com

kuangbin專題一 簡單搜索 題解

上下 bst turn str 表示 stream 就是 += find 目錄 [kuangbin帶你飛]專題一 簡單搜索 [kuangbin帶你飛]專題一 簡單搜索 總結:用時2天半終於把這個專題刷完了 對於最基礎的dfs bfs 路徑打印 狀態轉移也有了一點自己些

I - Fire! ~~ [kuangbin]專題一 簡單搜尋

題目描述 喬在迷宮中工作。不幸的是,迷宮的一部分著火了,迷宮的主人沒有制定火災的逃跑計劃。請幫助喬逃離迷宮。根據喬在迷宮中的位置以及迷宮的哪個方塊著火,你必須確定火焰燒到他之前,喬是否可以離開迷宮,如果能離開他能跑多快。 喬和火每分鐘移動一個方格,上、下、左、右,四個方向中的一個。火勢向四個方向

O - Meteor Shower ~~~ [kuangbin]專題一 簡單搜尋

Description - 題目描述 Bessie聽說有場史無前例的流星雨即將來臨;有讖言:隕星將落,徒留灰燼。為保生機,她誓將找尋安全之所(永避星墜之地)。目前她正在平面座標系的原點放牧,打算在群星斷其生路前轉移至安全地點。 此次共有M (1 ≤ M ≤ 50,000)

M - Find a way ~~~ [kuangbin]專題一 簡單搜尋

hsj和lsh最近迷上了pokemon go的遊戲。在雙十一大物期中考試來臨之前,他們想抓一隻稀有土撥鼠來攢攢人品(因為土撥鼠的重新整理地點最近來到了哈工程) 但是由於土撥鼠過於強大,他的雷霆半月斬以及驚天浪濤沙都可以輕鬆的將他們兩擊敗,但是他們兩的合擊必殺技流影電光閃以及天羽屠鼠舞可以將土撥鼠打至

L - 非常可樂 ~~ [kuangbin]專題一 簡單搜尋

大家一定覺的運動以後喝可樂是一件很愜意的事情,但是seeyou卻不這麼認為。因為每次當seeyou買了可樂以後,阿牛就要求和seeyou一起分享這一瓶可樂,而且一定要喝的和seeyou一樣多。但seeyou的手中只有兩個杯子,它們的容量分別是N 毫升和M 毫升 可樂的體積為S (S<101)毫

N - Red and Black ~~ [kuangbin]專題一 簡單搜尋

有一個長方形的房間,覆蓋了正方形的磁磚。每塊磁磚的顏色,要麼是紅色,要麼是黑色。一名男子站在一塊黑色的磁磚上。他可以從一塊磁磚移至相鄰四塊磁磚中的某一塊。但是,他不允許在紅色磁磚上移動,他只允許在黑色磁磚上移動。 編寫一個程式,使得他允許重複上述的移動,判斷他所能到達的黑色磁磚的數量。 輸入

K - Oil Deposits ~~ [kuangbin]專題一 簡單搜尋

GeoSurvComp地質調查公司負責探測地下石油儲藏。 GeoSurvComp現在在一塊矩形區域探測石油,並把這個大區域分成了很多小塊。他們通過專業裝置,來分析每個小塊中是否蘊藏石油。如果這些蘊藏石油的小方格相鄰,那麼他們被認為是同一油藏的一部分。在這塊矩形區域,可能有很多油藏。你的任務是確定有多

F - Prime Path ~~ [kuangbin]專題一 簡單搜尋

給你兩個四位的素數a,b。 a可以改變某一位上的數字變成c,但只有當c也是四位的素數時才能進行這種改變。 請你計算a最少經過多少次上述變換才能變成b。 例如:1033 -> 8179 1033 1733 3733 3739 3779 8779 8179 最少變換了6次。 Input 第

E - Find The Multiple ~ [kuangbin]專題一 簡單搜尋

給定一個正整數n,請編寫一個程式來尋找n的一個非零的倍數m,這個m應當在十進位制表示時每一位上只包含0或者1。你可以假定n不大於200且m不多於100位。 提示:本題採用Special Judge,你無需輸出所有符合條件的m,你只需要輸出任一符合條件的m即可。 Input 輸入包含多組資料,

C - Catch That Cow ~ [kuangbin]專題一 簡單搜尋

  農夫知道一頭牛的位置,想要抓住它。農夫和牛都於數軸上 ,農夫起始位於點 N(0<=N<=100000) ,牛位於點 K(0<=K<=100000) 。農夫有兩種移動方式: 1、從 X移動到 X-1或X+1 ,每次移動花費一分鐘 2、從 X移動到 2*X ,每

A - 棋盤問題 ~ [kuangbin]專題一 簡單搜尋

在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請程式設計求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。 Input 輸入含有多組測試資料。 每組資料的第一行是兩個正整數,n k,用一個空格隔

[kuangbin]專題一 簡單搜尋

The ministers of the cabinet were quite upset by the message from the Chief of Security stating that they would all have to change the four-digit room numb

[kuangbin]專題一 簡單搜尋 題解報告

又重頭開始刷kuangbin,有些題用了和以前不一樣的思路解決。全部題解如下 點選每道題的標題即可跳轉至VJ題目頁面。 A-棋盤問題 棋子不能擺在相同行和相同列,所以我們可以依此列舉每一行,然後標記每一列是否走過,在此基礎上進行DFS即可。 程式碼如下: 1 #include <i

[kuangbin]專題二-搜尋進階-D-Escape

ACM模版 描述 題解 這種問題不難,無非兩點,一:看懂題,二:細心。 矩陣的搜尋一般使用 bfs 比較多,也比較好,這裡的標記要用一個三維陣列,多出來的一維用來標記時間,記住要用 bool 型,習慣性的使用 int 型會爆記憶體的,其他也沒

[kuangbin]專題四 最短路練習 A-D

  上了大二,又有新生來了,壓力也來了,不能像大一這麼鬆懈了,所以開始每天刷刷題,想根據專題一個知識點一個知識點過   今天是最短路專題,對於最短路,能想到的方法大概就是dijkstra演算法(求單源最短路不含負環)O(n^2)如果使用堆優化,就是O(mlogn),還有就是floyd演算法(求圖上任意兩點的

[kuangbin]專題十六 KMP & 擴充套件KMP & Manacher 題解報告

來刷kuangbin字串了,字串處理在ACM中是很重要的,一般比賽都會都1——2道有關字串處理的題目,而且不會很難的那種,大多數時候都是用到一些KMP的性質或者找規律。 點選標題可跳轉至VJ比賽題目連結。 A - Number Sequence 題意就是讓你去找在串A找串B首次出現的位置,現在串不是字串

[kuangbin]專題十三 基礎計算幾何A

A - TOYS Calculate the number of toys that land in each bin of a partitioned toy box.  Mom and dad have a problem - their child John never puts his toy