幾種特殊的產生樹

來源:互聯網
上載者:User

1.(嚴格)次小產生樹

解法:1.依次刪除樹上的邊後求最小產生樹,判產生樹唯一時只需刪存在與它長度相同的邊,嚴格次小產生樹只需刪沒有與自己長度相同的邊。

            2.以最小產生樹上每個點為根dfs,求出樹上任意兩點之間的最長邊。枚舉所有不在最小產生樹上的邊,將其添加到樹上必定形成一個環,去掉環上的最長邊形成的產生樹最小。判斷產生樹是否唯一,求次小產生樹嚴格次小產生樹等均在此處處理。

void work(){best=new int[n][n];vis=new boolean[n];for(int i=0;i<n;i++){Arrays.fill(vis, false);dfs(i,i);}int min=99999999;for(int i=0;i<m;i++)if(!ed[i].flag)if(mst+ed[i].v-best[ed[i].a][ed[i].b]<min)min=mst+ed[i].v-best[ed[i].a][ed[i].b];}void dfs(int v,int a){vis[a]=true;for(int i=E[a];i!=-1;i=buf[i].ne){int b=buf[i].be;if(!vis[b]){best[v][b]=Math.max(best[v][a], buf[i].dis);dfs(v,b);}}}

題目:Ural 1416. Confidential 要求最小產生樹和次小產生樹,注意判連通性。

      Poj 1679 The Unique MST判斷最小產生樹是否唯一


2.最小度限制產生樹

 把頂點V的度數<= K 稱做度限制條件,把滿足這一條件的產生樹叫做度限制產生樹,把權值和最小的度限制產生樹稱最小度限制產生樹。

解法:1.把頂點去除,對其他點邊使用kruskal求產生樹,並求出共有m個連通分量。

      2.一次添加頂點到各個連通分量的最短邊,得到m度最小產生樹,若m>k則不存在k度產生樹。

      3.dfs求出m度產生樹上頂點到各個點間路徑上的最長邊best[i]。

      4.依次次遍曆從頂點出發的為添加到m度最小產生樹的邊,求出best[ed[j].a] - ed[j].dis>0且最大的一條邊,添加到k度產生樹中。

      5.重複4知道m==k或不存在那樣一條邊。

題目:poj 1639 Picnic Planning 


3.最優比例產生樹

一個帶權完全圖,每條邊都有自己的花費值cost[i]和
長度dis[i],
求一個產生樹,使得r=(∑cost[i]*x[i] ) / (∑dis[i]*x[i] )最小。

解法:詳見《0-1分數規劃問題》

題目:poj2526 Desert King


4.最小樹形圖

有向圖的最小產生樹,並且規定了起點。

解法:1.首先dfs判斷一下起點可達其他任意點,否則不存在樹形圖。

      2.為每個點找一條最小的入邊,如果沒環那麼這些邊就構成了最小樹形圖,轉入4;否則轉入3.

      3.將環上每條邊的邊權加入到ans中,同時形成新的點new,對於環內多有的點i,如果存在邊<j,i>則<j,new>的邊權等於所有 <j,i>-<pre[i],i>中最小的(因為縮點後再次構圖必須從環中去除一條邊<pre[i],i>再添加一條最小邊<x,i>,這樣就可以保證答案的正確性,很巧妙,換個圖就很清晰了),<new,j>的邊權=所有<i,j>的最小值,縮點完成,轉向2.

      4.縮點後n個點,n-1條邊,切無環,此時就是一顆連通樹了,ans+=這n-1條邊的邊權記得答案;

以上是國人發明的“朱劉演算法”,鄰接矩陣複雜度(n ^3)臨界表複雜度(VE)。

對於跟不固定的情況,wy教主有一巧妙方法,今後再去實現。摘錄如下:
新加一個點,和每個點連權相同的邊,這個權大於原圖所有邊權的和,這樣這個圖固定跟的最小樹形圖和原圖不固定跟的最小樹形圖就是對應的了。

題目:Poj3164 Command Network

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.StreamTokenizer;import java.util.Arrays;public class Command3164 {class point {int x, y;double dis(point o) {double temp = (x - o.x) * (x - o.x) + (y - o.y) * (y - o.y);return Math.sqrt(temp);}}double map[][] = new double[110][110], inf = 99999999.99;int pre[] = new int[110];boolean vis[] = new boolean[110], is[] = new boolean[110];void build() {for (int i = 2; i <= n; i++)if (!vis[i]) {pre[i] = 1;for (int j = 2; j <= n; j++)if (i != j && !vis[j] && map[pre[i]][i] > map[j][i])pre[i] = j;}}boolean bcc() {for (int i = 2; i <= n; i++) {if (vis[i])continue;Arrays.fill(is, false);int j;for (j = i; j != 1 && !is[j]; j = pre[j])is[j] = true;if (j == 1)continue;// j存在自環,環內所有點所為jans += map[pre[j]][j];for (i= pre[j]; i!= j; i = pre[i]) {ans += map[pre[i]][i];vis[i] = true;}//縮點for (int k = 1; k <= n; k++)if (!vis[k] && map[k][j] < inf)map[k][j] -= map[pre[j]][j];for (i = pre[j]; i!= j; i = pre[i])// 處理環內所有點的邊for (int k = 1; k <= n; k++)if (!vis[k]) {map[j][k] = Math.min(map[j][k], map[i][k]);// 出邊if (map[k][i] < inf)map[k][j] = Math.min(map[k][j], map[k][i]// 入邊- map[pre[i]][i]);}return true;}return false;}void dfs(int x) {vis[x] = true;cnt++;for (int i = 1; i <= n; i++)if (!vis[i] && map[x][i] < inf)dfs(i);}int cnt;void work() {cnt = 0;Arrays.fill(vis, false);dfs(1);if (cnt < n) {System.out.println("poor snoopy");return;}Arrays.fill(vis, false);while (true) {build();if (!bcc())break;}for (int i = 2; i <= n; i++)if (!vis[i])ans += map[pre[i]][i];System.out.println(String.format("%.2f", ans));}void init() throws IOException {ans = 0;for (int i = 1; i <= n; i++) {Arrays.fill(map[i], inf);pp[i] = new point();pp[i].x = next();pp[i].y = next();}int a, b;while (m-- > 0) {a = next();b = next();map[a][b] = Math.min(map[a][b], pp[b].dis(pp[a]));}}point pp[] = new point[110];int n, m;double ans;StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));int next() throws IOException{in.nextToken();return (int)in.nval;}void run() throws IOException {while (in.nextToken()!=in.TT_EOF) {n = (int)in.nval;m =next();init();work();}}public static void main(String[] args) throws IOException {new Command3164().run();}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.