暑訓day8 生成樹相關

2021-08-22 15:22:22 字數 3866 閱讀 8129

了解各類生成樹之前,先花了半天研究最小生成樹和構造他的prim演算法。

大體講prim演算法的建樹過程類似貪心,每次都選最小邊,只不過選的基準在變,不能用傳統的貪心來做,prim在貪心的同時要不斷更新周圍邊的權值大小,從而構造出最小生成樹。值得一提的是對於傳統的prim,這裡有乙個通過佇列優化的prim演算法。

//優化後,優先佇列nlogn

struct node

};int prim(int cur ,int

id) }}

}return ans;

}

最小生成樹之後還有次小生成樹,字面意思唄。

相對於構建最小生成樹,多了以下步驟(同時要在prim中標記used[i][j],即(i,j)這條邊是否用過)

int second_tree()//求次小生成樹  

其次,最小限度生成樹(也稱最小k度生成樹),其實就是在根節點連了k個子樹後求乙個最小生成樹。

大致思路是,不管根節點,求根節點除外的森林中的每個最小生成樹,然後通過加邊比較刪最大邊再換邊的一系列操作是各個生成樹與根節點相連,構成最小k度生成樹。

a poj 1639 picnic planning

題目大意:公園只有三個停車場,給出很多人之間或與公園的距離,相遇後可擠在同一輛車生前往往下個目的地,問到公園最少開車距離。

很顯然,求最小三度生成樹

**

#include

#include

#include

#include

#include

#define inf 0x3f3f3f

using

namespace

std;

const

int n=30;

struct node

};map

mp;

int g[n][n],dis[n],clo[n],pre[n],fst[n],max_side[n];

int n,m,k;

int prim(int cur,int id)}}

}return ans;

} void update(int cur,int last,int maxside)

}void solve()

int res=0,cnt=0;

for(int i=1; iif(!clo[i])

res+=prim(i,++cnt);

}for(int i=1; i//不斷更新與0連線的各樹最小邊

for(int i=1; i<=cnt; i++)

k=k-cnt;

while(k--)

if(max_side[tmp]<=g[0][tmp])

break;

res=res-max_side[tmp]+g[0][tmp];

g[0][tmp]=g[tmp][0]=0;

int p=0;

for(int i=tmp; pre[i]!=0; i=pre[i])

if(p==0||g[p][pre[p]]0;

update(tmp,0,0);

}printf("total miles driven: %d\n",res);

} int main()

if(mp.count(s2)==0)

int u=mp[s1],v=mp[s2];

if(g[u][v]==0||g[u][v]>d)

}cin>>k;

solve();

return

0;}

之後,最優比率生成樹。了解這個之前,先了解01規劃。(網上很多)

經典思想——二分即可.

建立在01規劃基礎上再加乙個建樹過程,即就是利用樹上的各類權值進行01規劃問題(據說有種迭代方法沒還沒來得及看)

c poj 2728 desert king

題意很明顯,就是01規劃

**

#include

#include

#include

#include

#include

using

namespace

std;

#define inf 0x3f3f3f

#define maxn 1005

int n;

int x[maxn], y[maxn], h[maxn];

double v[maxn][maxn], c[maxn][maxn];

int vis[maxn];

double w[maxn];

double prim(double r)

vis[1]=1;

for(int i=1;ifor(int j=1;j<=n;j++)

}mincost+=min;

vis[next]=1;

for(int j=1;j<=n;j++)}}

return mincost;

}int main()

}double l=minnv/maxnc;

double r=maxnv/minnc;

double mid;

while(r-l>1e-6)

printf("%.3f\n",mid);

}return

0;}

特別注意這道題的資料型別和範圍。

然後,最優比率環(沒做)。

然後,最小樹形圖(沒做)。

然後,然後就到二分匹配了。

二分圖匹配衍生出來的問題大都同一解法,關鍵在於理解二分匹配

這裡有幾篇非常贊的文章了解一下

講的一些概念的區分和關係

二分圖最大匹配的könig定理及其證明

二分圖大講堂

一般裸二分題目套路都是差不多(同乙個模板??),重點是理解二分圖中每乙個小概念(尤其是增廣路)和一下核心**(匈牙利演算法)。

int find(int cur)

}}

return

0;}

遍歷

for(int i=1;i<=m;i++)

k poj 1486 sorting slides

很有意思,只要想到合適的構圖方法,就很容易想到用二分圖匹配來做

**

#include 

#include

#include

#include

#include

#include

#define maxn 510

using

namespace

std;

bool vis[maxn];

intmap[maxn][maxn],m,pre[maxn];

int n;

struct tagt[maxn];

struct nodenode[maxn];

int find(int cur)}}

return0;}

int main()

for(int i=1;i<=n;i++)

for(int i=1;i<=n;i++)}}

int sum = 0;

for(int i = 1; i <=n; i++)

int t,flag=0;

for(int i=1;i<=n;i++)

map[t][i]=1;

}if(flag==0)

printf("none");

printf("\n\n");

}return

0;}

接下來是ramsey定理(還沒看到)

牛客 11 01 生成樹

你有一張n個點的完全圖 即任意兩點之間都有無向邊 現在給出這張圖的兩棵生成樹 定義一次操作為 在任意一棵生成樹中刪除一條邊後再加入一條邊 必須在同一棵樹中操作 同時需要保證操作完後仍然是一棵樹 問使得兩棵樹相同的最少操作次數,若不存在合法的操作方案,輸出 1 注意 這裡的相同指的是點集與邊集均相同,...

day 8 字串相關方法

字串內建方法 dir 查詢這個型別的資料有什麼操作方法 通過ctrl 滑鼠鍵可以檢視使用方法str1 hello world print dir str1 capitalize 整個字串的首字母大寫 str2 str1.capitalize print str2 title 每個單詞的首字母大寫 s...

uva 10766 生成樹計數

給出n,m,k,代表一家公司有n個部門,編號1到n,有m組關係,表示i和j不能直接聯通,k代表主管部門,問你有多少種分層方案。這道題的k沒有什麼用。include include include include include include include include include incl...