青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

次小生成樹(shù)的一種極其神犇的算法

Posted on 2011-07-01 09:10 Mato_No1 閱讀(2775) 評(píng)論(8)  編輯 收藏 引用 所屬分類(lèi): 圖算法
相關(guān)鏈接

Orz AHdoc!!!!!!!!!!!!!

這種神犇算法的關(guān)鍵在于真正利用了MST是一棵“樹(shù)”的性質(zhì)。也就是,它在求出MST后把它轉(zhuǎn)化為有根樹(shù),然后,按長(zhǎng)度遞增順序對(duì)于圖中每一條不在MST中的邊(i, j),找到樹(shù)中i、j的最近公共祖先(LCA),記為p=LCA(i, j)。這樣,樹(shù)中i->p->j就是從i到j(luò)的路徑。然后,依次掃描這條路徑上的所有的邊,將新邊(i, j)的長(zhǎng)度與路徑上所有邊的長(zhǎng)度比較,找到長(zhǎng)度差最小的(不過(guò)由于邊(i, j)的長(zhǎng)度一定不小于路徑上所有邊的長(zhǎng)度,所以只要找到路徑上最長(zhǎng)邊,則“刪去這條最長(zhǎng)邊,加入邊(i, j)”一定是所有加入的邊為(i, j)的可行變換中代價(jià)最小的),取這個(gè)長(zhǎng)度差最小的即可。不過(guò)最為神犇的一點(diǎn)是,這個(gè)算法在遍歷完這條路徑后,會(huì)將路徑上所有的點(diǎn)(p點(diǎn)除外)的父結(jié)點(diǎn)全部設(shè)為p,也就是相當(dāng)于并查集的路徑壓縮!這雖然會(huì)改變樹(shù)的形態(tài),但任何兩點(diǎn)的LCA都是不會(huì)變的,因此不會(huì)影響后面的邊。

注意上面“按長(zhǎng)度遞增順序”是重點(diǎn),原因是“路徑壓縮”可能會(huì)改變某些點(diǎn)之間的路徑,也就是將某些點(diǎn)之間的路徑長(zhǎng)度減小。但是,很容易發(fā)現(xiàn),被“壓縮”的這些邊必然是已經(jīng)訪問(wèn)過(guò)的,也就是說(shuō)這些邊必然已經(jīng)作為了前面的某條邊(i, j),i到j(luò)路徑上的邊。對(duì)于這條邊來(lái)說(shuō),可行變換中,新加入的邊的長(zhǎng)度應(yīng)盡量小,因此,如果按長(zhǎng)度遞增順序,則這些邊在(i, j)之后肯定不會(huì)出現(xiàn)代價(jià)更小的可行變換,因此就可以將它們壓縮,不會(huì)影響最優(yōu)解。

復(fù)雜度分析:先不管求LCA的時(shí)間復(fù)雜度。設(shè)樹(shù)中結(jié)點(diǎn)i的深度為h[i](h[root]=0)。對(duì)于樹(shù)中的任意一個(gè)葉結(jié)點(diǎn)v,從root到v的路徑的總長(zhǎng)度(總邊數(shù))為h[v],因此,若某次要嘗試的邊(i, j)的某一端點(diǎn)(設(shè)為i)在從root到v的這條路徑上,則p=LCA(i, j)一定也在這條路徑上。這樣,訪問(wèn)從i到p的路徑上的總訪問(wèn)次數(shù)(也就是從i到p路徑上的邊數(shù))為(h[i]-h[p])。在訪問(wèn)完成后,需要將從i到p路徑上除p外的所有結(jié)點(diǎn)的父結(jié)點(diǎn)都設(shè)為p,也就是從root到v的路徑的總長(zhǎng)度減少了(h[i]-h[p]-1)。因此,在嘗試所有不在MST中的邊的過(guò)程中,訪問(wèn)從root到v的最初路徑上的邊的總次數(shù)不會(huì)超過(guò)(h[v]+這些邊的總數(shù))(這里h[v]指初始的h[v])。因此可以得到:訪問(wèn)樹(shù)中所有邊的總次數(shù)不會(huì)超過(guò)(最初所有葉結(jié)點(diǎn)深度之和+2*M),M為所有不在MST中邊的總數(shù)!由于“最初所有葉結(jié)點(diǎn)深度之和”不會(huì)超過(guò)Nlog2N,因此總時(shí)間復(fù)雜度為O(Mlog2M+M+Nlog2N),其中O(Mlog2M)為用Kruskal求MST的時(shí)間,如果忽略這部分時(shí)間,則總時(shí)間復(fù)雜度為O(M+Nlog2N)。
其實(shí)這個(gè)算法的時(shí)間復(fù)雜度在忽略排序的情況下是線性的,即O(M+N),但本沙茶搞不懂怎么證明這一步。

下面是具體實(shí)現(xiàn)時(shí)的注意事項(xiàng):
(1)將MST轉(zhuǎn)化為有根樹(shù)時(shí),應(yīng)用BFS,而不要用DFS,否則對(duì)于特殊數(shù)據(jù)可能爆棧;
(2)求LCA時(shí),應(yīng)用先讓深度大的結(jié)點(diǎn)向上的方法(AHdoc神犇的方法),具體見(jiàn)下面的代碼片段1;或者應(yīng)用兩者同時(shí)往上的方法(本沙茶的方法),具體見(jiàn)下面的代碼片段2;否則,對(duì)于樹(shù)是一條鏈,且每次訪問(wèn)都是訪問(wèn)最深的兩個(gè)結(jié)點(diǎn)時(shí),一次求LCA的時(shí)間復(fù)雜度可能升到O(N)。

【代碼片段1】
int lca(int a, int b)
{
    
for (;;)
    {
        
if (a == b) return b;
        
if (h[a] >= h[b]) a = Fa[a]; else b = Fa[b];
    }
}
【代碼片段2】
int LCA(int x, int y)
{
    
while (x && y) {
        
if (fl[x] == _s) return x; else fl[x] = _s;
        
if (fl[y] == _s) return y; else fl[y] = _s;
        x 
= pr[x]; y = pr[y];
    }
    
if (x) while (1if (fl[x] == _s) return x; else x = pr[x]; else while (1if (fl[y] == _s) return y; else y = pr[y];
}

【具體題目】Beijing2010 Tree(BZOJ1977)
這題要求嚴(yán)格次小生成樹(shù),因此在枚舉的時(shí)候要注意,不能使可行變換的代價(jià)為0。
#include <iostream>
#include 
<stdio.h>
#include 
<algorithm>
using namespace std;
#define re(i, n) for (int i=0; i<n; i++)
#define re1(i, n) for (int i=1; i<=n; i++)
const int MAXN = 100001, MAXM = 300001;
const long long INF = ~0Ull >> 2;
struct edge {
    
int a, b, len;
    friend 
bool operator< (edge e0, edge e1) {return e0.len < e1.len;}
} E[MAXM];
struct edge0 {
    
int a, b, id, pre, next;
} E0[MAXM 
+ MAXM];
int n, m, m0, u[MAXN], pr[MAXN], No[MAXN], s[MAXM], Q[MAXN], fl[MAXN], _s;
long long mst_v = 0, res;
bool inmst[MAXM], vst[MAXN];
void init()
{
    scanf(
"%d%d"&n, &m);
    re(i, m) scanf(
"%d%d%d"&E[i].a, &E[i].b, &E[i].len);
}
int find(int x) {int r = x, r0; while (u[r] > 0) r = u[r]; while (u[x] > 0) {r0 = u[x]; u[x] = r; x = r0;} return r;}
void uni(int s1, int s2) {int tmp = u[s1] + u[s2]; if (u[s1] > u[s2]) {u[s1] = s2; u[s2] = tmp;} else {u[s2] = s1; u[s1] = tmp;}}
void init_d()
{
    re1(i, n) {E0[i].a 
= i; E0[i].pre = E0[i].next = i;}
    
if (n % 2) m0 = n + 1else m0 = n + 2;
}
void add_edge(int a, int b, int id)
{
    E0[m0].a 
= a; E0[m0].b = b; E0[m0].id = id; E0[m0].pre = E0[a].pre; E0[m0].next = a; E0[a].pre = m0; E0[E0[m0].pre].next = m0++;
    E0[m0].a 
= b; E0[m0].b = a; E0[m0].id = id; E0[m0].pre = E0[b].pre; E0[m0].next = b; E0[b].pre = m0; E0[E0[m0].pre].next = m0++;
}
void prepare()
{
    sort(E, E 
+ m);
    re1(i, n) u[i] 
= -1; init_d();
    
int s1, s2, z = 0;
    re(i, m) {
        s1 
= find(E[i].a); s2 = find(E[i].b);
        
if (s1 != s2) {z++; mst_v += E[i].len; add_edge(E[i].a, E[i].b, i); inmst[i] = 1; uni(s1, s2); if (z == n - 1break;}
    }
}
void bfs()
{
    re1(i, n) vst[i] 
= 0;
    Q[
0= 1; vst[1= 1;
    
int i, j;
    
for (int front=0, rear=0; front<=rear; front++) {
        i 
= Q[front];
        
for (int p=E0[i].next; p != i; p=E0[p].next) {
            j 
= E0[p].b;
            
if (!vst[j]) {
                vst[j] 
= 1; Q[++rear] = j; pr[j] = i; No[j] = E0[p].id;
            }
        }
    }
}
int LCA(int x, int y)
{
    
while (x && y) {
        
if (fl[x] == _s) return x; else fl[x] = _s;
        
if (fl[y] == _s) return y; else fl[y] = _s;
        x 
= pr[x]; y = pr[y];
    }
    
if (x) while (1if (fl[x] == _s) return x; else x = pr[x]; else while (1if (fl[y] == _s) return y; else y = pr[y];
}
void sol0(int a, int b, int l)
{
    
int p = LCA(a, b), p0, No0;
    
while (a != p) {No0 = No[a]; if (!s[No0] && l > E[No0].len) s[No0] = l - E[No0].len; p0 = pr[a]; pr[a] = p; a = p0;}
    
while (b != p) {No0 = No[b]; if (!s[No0] && l > E[No0].len) s[No0] = l - E[No0].len; p0 = pr[b]; pr[b] = p; b = p0;}
}
void solve()
{
    pr[
1= 0; bfs();
    re(i, m) 
if (!inmst[i]) {_s = i + 1; sol0(E[i].a, E[i].b, E[i].len);}
    res 
= INF;
    re(i, m) 
if (inmst[i] && s[i] && s[i] < res) res = s[i];
    res 
+= mst_v;
}
void pri()
{
    cout 
<< res << endl;
}
int main()
{
    init();
    prepare();
    solve();
    pri();
    
return 0;
}

Feedback

# re: 次小生成樹(shù)的一種極其神犇的算法  回復(fù)  更多評(píng)論   

2011-08-04 13:14 by 南京康輝旅行社
謝謝,正在找呢。。

# re: 次小生成樹(shù)的一種極其神犇的算法  回復(fù)  更多評(píng)論   

2011-11-16 18:38 by Seter
看了半天還是覺(jué)得神犇您的程序是錯(cuò)誤的啊。下面這個(gè)數(shù)據(jù)答案應(yīng)該是6,您的程序輸出7:
4 5
1 4 1
2 3 1
1 2 3
3 4 3
3 4 4
問(wèn)題在于,路徑壓縮的正確性是建立在選擇路徑上的最大邊的條件上的,而您的嚴(yán)格次小生成樹(shù)忽略了權(quán)值相等的邊,使得可行變換的單調(diào)性無(wú)法維持。
路徑壓縮時(shí)修改邊權(quán)可能可以解決這一問(wèn)題。

# re: 次小生成樹(shù)的一種極其神犇的算法[未登錄](méi)  回復(fù)  更多評(píng)論   

2011-11-24 17:04 by xiaodao
@Seter
是有重邊的緣故么?

# re: 次小生成樹(shù)的一種極其神犇的算法  回復(fù)  更多評(píng)論   

2011-11-28 18:50 by Seter
@xiaodao
重邊是最簡(jiǎn)單的一種可以導(dǎo)致這個(gè)算法錯(cuò)誤的情況……
這個(gè)證明是建立在“不嚴(yán)格”的基礎(chǔ)下的……
如果要應(yīng)用于“嚴(yán)格”,那么必須修改算法并且重新證明……

# re: 次小生成樹(shù)的一種極其神犇的算法  回復(fù)  更多評(píng)論   

2011-12-04 12:13 by Mato_No1
@xiaodao
找到問(wèn)題了,
問(wèn)題并不在于重邊,而是在于出現(xiàn)權(quán)值相等的邊的時(shí)候,由于嚴(yán)格次小生成樹(shù)的定義,這種變換(就是用權(quán)值相等的邊來(lái)替換)是不可行的,然而緊接著又把它們壓縮掉了,這樣,接下來(lái)這條路徑上出現(xiàn)權(quán)值不相等的邊的時(shí)候由于壓縮,就把某些可行變換給搞丟了,
比如,
P-3-O-1-Z-1-X
\
1
\
O-3-O-3-O-1-W-1-Y
(P表示LCA,O、Z、W表示中間結(jié)點(diǎn),兩個(gè)結(jié)點(diǎn)間的數(shù)字表示邊權(quán))
然后,先是掃描到一條邊(X, Y)權(quán)值為3,發(fā)現(xiàn)只能和那些權(quán)值為1的邊之間形成可行變換,最小代價(jià)為2,于是就壓縮了,但是在此之后又出現(xiàn)了一條邊(Z, W)權(quán)值為4,此時(shí)它們之間的長(zhǎng)度為3的那些邊就找不到了,導(dǎo)致最優(yōu)解(代價(jià)為1)丟失。

一種解決方法是遇到這種情況就徹底不壓縮,或者是只壓縮與P最近的那些權(quán)值不相等的邊,但是在某些極端情況下復(fù)雜度可能退化到O(NM)……

神犇們有更好的解決方法么囧?急求

# re: 次小生成樹(shù)的一種極其神犇的算法  回復(fù)  更多評(píng)論   

2012-02-02 19:11 by Seter
@Mato_No1
我的想法是這樣的:1.每次不僅找i->p->j上的最長(zhǎng)邊,還要找嚴(yán)格次長(zhǎng)邊。2.路徑壓縮時(shí),新邊i->p的長(zhǎng)度設(shè)為i->p這條路徑上的最長(zhǎng)的長(zhǎng)度。
我稍微證了一下,這個(gè)應(yīng)該沒(méi)什么問(wèn)題了。

# re: 次小生成樹(shù)的一種極其神犇的算法  回復(fù)  更多評(píng)論   

2012-02-03 09:08 by Seter
LS在瞎說(shuō),請(qǐng)神犇們無(wú)視!
難道真的無(wú)解了么……

# re: 次小生成樹(shù)的一種極其神犇的算法  回復(fù)  更多評(píng)論   

2012-09-03 18:54 by void_rank
5 6
1 2 1
1 3 8
2 4 8
4 5 1
3 4 10
4 3 3

好像神犇的這個(gè)數(shù)據(jù)跪了,是不是我的測(cè)試方法不對(duì),求證實(shí)?

然后我看完上面的回復(fù)好像發(fā)現(xiàn)了lz的問(wèn)題,代碼沒(méi)改過(guò)來(lái)么。。。。。
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美视频在线视频| 亚洲第一综合天堂另类专| 欧美日韩免费观看一区三区 | 亚洲一区在线播放| 国产精品不卡在线| 欧美日韩综合| 国产精品久久久久av| 国产精品热久久久久夜色精品三区 | 欧美大片网址| 午夜亚洲一区| 久久国产直播| 老色鬼精品视频在线观看播放| 久热精品视频| 亚洲第一区在线观看| 亚洲精品一区二区三| 99国产一区二区三精品乱码| 亚洲视频在线一区观看| 午夜欧美视频| 欧美不卡在线| 国产精品久久久久99| 国语精品中文字幕| a4yy欧美一区二区三区| 欧美主播一区二区三区| 欧美激情精品久久久六区热门| 亚洲美女福利视频网站| 欧美亚洲系列| 欧美精品久久久久久久免费观看| 国产精品视频999| 亚洲高清在线观看| 亚洲免费视频在线观看| 麻豆freexxxx性91精品| 亚洲视频中文字幕| 欧美成人午夜激情在线| 国产一区二区高清| 亚洲自拍偷拍麻豆| 亚洲国产成人久久综合一区| 亚洲欧美激情一区| 欧美精品一区二区三区在线播放| 国产一区二区毛片| 亚洲综合视频1区| 欧美高清在线观看| 久久精品国产99精品国产亚洲性色 | 媚黑女一区二区| 夜夜嗨一区二区| 欧美国产激情二区三区| 国产亚洲免费的视频看| 亚洲尤物视频在线| 亚洲免费成人| 欧美高清日韩| 亚洲国产一区二区精品专区| 新狼窝色av性久久久久久| 9l国产精品久久久久麻豆| 欧美成人中文| 亚洲激情视频网站| 欧美大片18| 免播放器亚洲| 亚洲第一精品电影| 久色婷婷小香蕉久久| 欧美怡红院视频| 国产丝袜一区二区三区| 香蕉久久夜色| 亚洲欧美日本视频在线观看| 国产精品美女午夜av| 亚洲欧美日韩电影| 亚洲一区二区三区在线视频| 国产精品国产精品国产专区不蜜| 国产伦理一区| 免费观看日韩av| 久久国产精品高清| 国内在线观看一区二区三区| 久久久久久香蕉网| 久久精品成人| 亚洲高清不卡一区| 亚洲成色777777在线观看影院| 久久偷窥视频| 日韩视频免费大全中文字幕| 亚洲精品老司机| 国产精品久久久久久久浪潮网站| 欧美与黑人午夜性猛交久久久| 久久gogo国模啪啪人体图| 一区二区三区亚洲| 亚洲国产精品成人综合色在线婷婷 | 一区二区三区国产在线观看| 欧美日韩免费观看一区=区三区| 亚洲午夜性刺激影院| 午夜激情综合网| 亚洲大胆在线| 日韩午夜免费视频| 国产视频在线观看一区二区三区| 久久在线免费| 欧美区一区二| 久久久av毛片精品| 欧美人与性动交a欧美精品| 亚洲综合电影| 久久久亚洲成人| 亚洲一区二区三区精品视频| 欧美一区二区三区视频在线观看| 亚洲国产精品久久久| 中文欧美在线视频| 一区二区视频在线观看| 亚洲精品乱码久久久久久久久| 国产精品美女久久久久久2018 | 在线视频亚洲一区| 伊人久久噜噜噜躁狠狠躁| 亚洲精品男同| 好吊成人免视频| 99re6热只有精品免费观看| 黑人中文字幕一区二区三区| aa级大片欧美三级| 91久久综合亚洲鲁鲁五月天| 亚洲一区二区三区精品在线观看 | 亚洲三级色网| 激情小说亚洲一区| 一区二区三区欧美激情| 亚洲国产精品毛片| 欧美一区二区视频观看视频| 夜夜嗨一区二区| 久久综合狠狠综合久久综合88| 小处雏高清一区二区三区| 欧美人与禽猛交乱配视频| 毛片基地黄久久久久久天堂| 国产精品亚洲成人| 亚洲乱码国产乱码精品精可以看 | 欧美午夜视频在线观看| 蜜臀av一级做a爰片久久| 国产九九视频一区二区三区| 亚洲精品乱码久久久久久日本蜜臀 | 欧美搞黄网站| 久久午夜影视| 国产日韩精品视频一区二区三区| 亚洲乱码视频| 日韩视频一区二区三区| 久久综合综合久久综合| 久久亚洲精品一区| 国产综合欧美| 久久久久久9| 久久久久久久网站| 国产在线播精品第三| 欧美在线观看视频一区二区三区| 欧美综合国产| 国产欧美日韩综合一区在线播放| 亚洲精品三级| 中日韩视频在线观看| 欧美丝袜一区二区| 日韩午夜免费视频| 亚洲欧美日韩一区在线| 国产精品久久久久久久午夜片| 一区二区三区高清在线| 亚洲欧美激情在线视频| 国产精品美女久久福利网站| 亚洲淫性视频| 久久久久久久综合色一本| 国产亚洲欧美一区二区| 久久久91精品国产| 欧美成人免费在线观看| 亚洲精品久久7777| 欧美日韩综合久久| 亚洲欧美美女| 久久久久久国产精品mv| 亚洲电影在线免费观看| 欧美黄色免费| 亚洲一级特黄| 女女同性精品视频| 亚洲精选91| 国产精品久久久久久久久搜平片 | 国产精品成人v| 午夜精品999| 欧美va天堂在线| 亚洲午夜精品久久久久久浪潮 | 国产精品入口日韩视频大尺度| 午夜精品久久久久久久久久久久久 | 午夜亚洲视频| 激情久久五月天| 欧美高清不卡在线| 亚洲在线视频观看| 欧美激情精品久久久久久免费印度 | 亚洲精选在线观看| 欧美在线视频一区二区三区| 亚洲高清不卡在线观看| 欧美午夜宅男影院在线观看| 久久精品2019中文字幕| 99视频超级精品| 久久全国免费视频| 亚洲视频欧美视频| 依依成人综合视频| 欧美新色视频| 麻豆乱码国产一区二区三区| 亚洲视频在线观看| 欧美激情小视频| 久久精品二区亚洲w码| 在线中文字幕一区| 亚洲第一二三四五区| 国产精品区一区| 欧美另类videos死尸| 久久精品国产精品亚洲综合 | 欧美精彩视频一区二区三区| 欧美中日韩免费视频| 亚洲视频播放| 亚洲精品一区二区三区av| 欧美成人免费全部|