两个吃奶一个添下面视频_人妻第一页香蕉网_欧美xxxx少妇_妺妺窝人体色www婷婷

說到斯坦納樹問題,它是一種組合優(yōu)化問題,與最小生成樹相似,是最短網(wǎng)絡(luò)的一種。最小生成樹是在給定的點(diǎn)集和邊中尋求最短網(wǎng)絡(luò)使所有點(diǎn)連通。而最小斯坦納樹允許在給定點(diǎn)外增加額外的點(diǎn),使生成的最短網(wǎng)絡(luò)開銷最小。

一、斯坦納樹

斯坦納樹問題是組合優(yōu)化問題,與最小生成樹相似,是最短網(wǎng)絡(luò)的一種,其實(shí)最小生成樹是最小斯坦納樹的一種特殊情況,最小生成樹是在給定的點(diǎn)集和邊中尋求最短網(wǎng)絡(luò)使所有點(diǎn)連通,而最小斯坦納樹允許在給定點(diǎn)外增加額外的點(diǎn),使生成的最短網(wǎng)絡(luò)開銷最小。


二、問題的提出

平原上的三個(gè)城鎮(zhèn)間要興建一個(gè)公用的煤氣供應(yīng)站,在選址問題上,要考慮的主要問題是使由供應(yīng)站到三個(gè)城鎮(zhèn)的輸送管道的總長(zhǎng)最短。如何去尋找合適地點(diǎn)?

假若要建的是一個(gè)垃圾處理站,要修建三條公路將垃圾站與三個(gè)城鎮(zhèn)連起來。這時(shí),因?yàn)槿齻€(gè)城鎮(zhèn)的居民的數(shù)目或工業(yè)性質(zhì)等的不同,每天運(yùn)送垃圾使用的車輛數(shù)目 各不相同,運(yùn)輸?shù)馁M(fèi)用也就各異。因此,選取地點(diǎn)時(shí),如果仍考慮使三條公路的總長(zhǎng)最小,就不合理了。

這時(shí)應(yīng)該考慮:先計(jì)算出三個(gè)城鎮(zhèn)單位時(shí)間內(nèi)生產(chǎn)的垃圾數(shù)量的百分比(或每日運(yùn)輸費(fèi)用的百分比),如何選取地點(diǎn),使得每個(gè)城鎮(zhèn)垃圾運(yùn)輸數(shù)量與公路里程的乘積之和為最小。

1638年,法國(guó)數(shù)學(xué)家費(fèi)馬在他所寫的一本關(guān)于求極值的書中就有了第一個(gè)問題,稱為費(fèi)馬問題

第二個(gè)問題則到了18世紀(jì)中葉才由辛普森(A.R.Simpson)提出來。


三、性質(zhì)

Pollak?Gilbert猜想:

平面上任意n點(diǎn)集,斯坦納最小樹長(zhǎng)與最小生成樹之長(zhǎng)的比值的最小值是Pollak?Gilbert猜想


四、求解

這個(gè)問題比較現(xiàn)實(shí),沒有太多需要解釋的地方

我們直接看解決方法:

首先我們知道,最優(yōu)解必然是一棵樹,這棵樹又是由若干棵子樹合并成的;

于是我們可以狀態(tài)壓縮,把 k 個(gè)節(jié)點(diǎn)的連通狀態(tài)用一個(gè)二進(jìn)制數(shù) j 表示;

dp[i][j]表示以 i 為根,與對(duì)應(yīng)狀態(tài)為 j 的節(jié)點(diǎn)連通的子樹的最小權(quán)值。

有兩種轉(zhuǎn)移方法:

枚舉子樹的形態(tài):dp[i][j]=min(dp[i][j],dp[i][k]+dp[i][l]),其中 k 和 l 是對(duì)j的一個(gè)劃分

按照邊進(jìn)行松弛:dp[i][j]=min(dp[i][j],dp[i′][j]+w[i][i′]),其中 i 和 i′ 之間有邊相連

對(duì)于第一種轉(zhuǎn)移,我們直接枚舉子集就行了

對(duì)于第二種轉(zhuǎn)移,我們仔細(xì)觀察可以發(fā)現(xiàn)這個(gè)方程和最短路的約束條件是很類似的,于是我們可以用spfa或者dijkstra來進(jìn)行狀態(tài)轉(zhuǎn)移

枚舉子集的復(fù)雜度枚舉子集的復(fù)雜度,spfa的復(fù)雜度為spfa的復(fù)雜度

所以總復(fù)雜度為總復(fù)雜度


五、實(shí)例

給定一個(gè)包含斯坦納樹個(gè)結(jié)點(diǎn)和斯坦納樹條帶權(quán)邊的無向連通圖無向連通圖。

再給定包含斯坦納樹個(gè)結(jié)點(diǎn)的點(diǎn)集斯坦納樹,選出斯坦納樹的子圖斯坦納樹,使得:

1. 斯坦納樹

2. 斯坦納樹為連通圖;

3. 斯坦納樹中所有邊的權(quán)值和最小。

你只需要求出斯坦納樹中所有邊的權(quán)值和。


輸入格式

第一行:三個(gè)整數(shù)斯坦納樹,表示斯坦納樹的結(jié)點(diǎn)數(shù)、邊數(shù)和斯坦納樹的大小。

接下來斯坦納樹行:每行三個(gè)整數(shù)斯坦納樹,表示編號(hào)為斯坦納樹的點(diǎn)之間有一條權(quán)值為斯坦納樹的無向邊。

接下來一行:斯坦納樹個(gè)互不相同的正整數(shù),表示斯坦納樹的元素。


輸出格式

第一行:一個(gè)整數(shù),表示斯坦納樹中邊權(quán)和的最小值。


輸入輸出樣例

斯坦納樹

說明/提示

【樣例解釋】

樣例中給出的圖如下圖所示,紅色點(diǎn)為斯坦納樹中的元素,紅色邊為斯坦納樹的元素,此時(shí)斯坦納樹中所有邊的權(quán)值和為 2+2+3+4=11,達(dá)到最小值。

所有邊的權(quán)值和為 2+2+3+4=11

【數(shù)據(jù)范圍】

對(duì)于 100% 的數(shù)據(jù),1≤斯坦納樹≤100,  1≤斯坦納樹≤500,  1≤斯坦納樹≤10,  1≤斯坦納樹,v≤斯坦納樹,  1≤斯坦納樹斯坦納樹

保證給出的無向圖連通,但可能存在重邊和自環(huán)。


參考代碼如下:

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define iinf 0x3f3f3f3f
#define linf (1ll<<60)
#define eps 1e-8
#define maxn 110
#define maxk 10
#define maxe 1010
#define cl(x) memset(x,0,sizeof(x))
#define rep(i,a,b) for(i=a;i<=b;i++)
#define drep(i,a,b) for(i=a;i>=b;i--)
#define em(x) emplace(x)
#define emb(x) emplace_back(x)
#define emf(x) emplace_front(x)
#define fi first
#define se second
#define de(x) cerr<<#x<<" = "<<x<<endl
using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll read(ll x=0)
{
    ll c, f(1);
    for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
    for(;isdigit(c);c=getchar())x=x*10+c-0x30;
    return f*x;
}
struct Graph
{
    int etot, head[maxn], to[maxe], next[maxe], w[maxe];
    void clear(int N)
    {
        for(int i=1;i<=N;i++)head[i]=0;
        etot=0;
    }
    void adde(int a, int b, int c=0){to[++etot]=b;w[etot]=c;next[etot]=head[a];head[a]=etot;}
    #define forp(_,__) for(auto p=__.head[_];p;p=__.next[p])
}G;
ll f[maxn][(1ll<<maxk)+10], n, m, k;
void dijkstra(ll s)
{
    priority_queue<pll,vector<pll>,greater<pll>> heap;
    ll i;
    rep(i,1,n)if(f[i][s]<linf)heap.em(pll(f[i][s],i));
    while(!heap.empty())
    {
        auto pr = heap.top(); heap.pop();
        if(pr.first!=f[pr.second][s])continue;
        forp(pr.second,G)
        {
            ll to = G.to[p];
            if(pr.first + G.w[p] < f[to][s])
            {
                f[to][s] = pr.first + G.w[p];
                heap.em( pll(f[to][s],to) );
            }
        }
    }
}
ll p[maxn];
int main()
{
    ll i, s, sub;
    n = read(), m = read(), k = read();
    rep(i,1,m)
    {
        ll u=read(), v=read(), w=read();
        G.adde(u,v,w);
        G.adde(v,u,w);
    }
    rep(i,1,n)rep(s,0,(1<<k)-1)f[i][s]=linf;
    rep(i,1,k)
    {
        p[i]=read();
        f[p[i]][1<<i-1]=0;
    }
    rep(s,0,(1<<k)-1)
    {
        rep(i,1,n)
            for(sub=s&(s-1);sub;sub=s&(sub-1))
                f[i][s] = min( f[i][s], f[i][sub] + f[i][s^sub] );
        dijkstra(s);
    }
    ll ans=linf;
    rep(i,1,n)ans=min(ans,f[i][(1<<k)-1]);
    printf("%lld",ans);
    return 0;
}


點(diǎn)贊(0)

C語言網(wǎng)提供由在職研發(fā)工程師或ACM藍(lán)橋杯競(jìng)賽優(yōu)秀選手錄制的視頻教程,并配有習(xí)題和答疑,點(diǎn)擊了解:

一點(diǎn)編程也不會(huì)寫的:零基礎(chǔ)C語言學(xué)練課程

解決困擾你多年的C語言疑難雜癥特性的C語言進(jìn)階課程

從零到寫出一個(gè)爬蟲的Python編程課程

只會(huì)語法寫不出代碼?手把手帶你寫100個(gè)編程真題的編程百練課程

信息學(xué)奧賽或C++選手的 必學(xué)C++課程

藍(lán)橋杯ACM、信息學(xué)奧賽的必學(xué)課程:算法競(jìng)賽課入門課程

手把手講解近五年真題的藍(lán)橋杯輔導(dǎo)課程

Dotcpp在線編譯      (登錄可減少運(yùn)行等待時(shí)間)