2019ICPC南昌邀請賽A題

2021-09-25 14:37:42 字數 1804 閱讀 2759

當時隊友都在做其他的題,我就去看了一下。。。先交幾發最小生成樹wa下,然後就走了

打完比賽dalao們說是斯坦納樹板板。。。行吧(打完比賽太多了,直到現在才有時間,計蒜客也出復現賽了,就去學了一下

先說一下a題題意:先給n個點,點的名字還是英文的,還要記錄一下,然後給出m條邊。之後給出4行,每行兩個點的名字,表示從點a到點b要有連線。如果4個連線有重複的邊,只需算一次。問最後所有對連起來所需要的最短的權值和

然後說一下斯坦納樹吧。。。斯坦納樹主要好像是求解 在圖中選擇幾個點,然後將幾個點連線起來的最短的權值和,最小生成樹是斯坦納樹的特殊情況emmmmmm

斯坦納樹主要是dp+最短路。在求解最短權值和的時候我們先會用

state1和state2是state兩個不同的狀態,state1|state2=state

這樣是第一步的優化

之後我們要用最短路來優化

dp[i][state]=min(dp[k][state]+map[k][i])

第二步優化,首先i k之間要有邊。。。基本和上面差不多

直到斯坦納樹和題意之後就可以套板板了。

但是有乙個問題,就是我們在求解的過程中,會發現用斯坦納樹來求的時候樹的根只有乙個,題目中給的樣例如果用這個方式來求解得出來的是25(這樣是求出一棵樹) 因為題目只需要我們求4對的連線,不需要有多餘的邊。。所以我們還要列舉一下。。。

列舉也不需要所有點列舉,畢竟n<=30,全部列舉超時了,我們只需要列舉給出的8個點。因為是4對,如果我們選了乙個點,那麼相對應的另乙個點我們也要選取(這是必須的),所以列舉最少乙個點,最多4個點(列舉想了好久。。。主要是先選點,然後選狀態)

ac**:

#include #include #include #include #include using namespace std;

typedef long long int ll;

const int maxm=1010;

const int maxn=35;

const ll inf=1e18;

struct node

map[maxm*2];

struct point

n[maxn];

int head[maxm],sum;

int n,m;

ll dp[maxn][maxm],bin[maxn],ans;

int lin[maxn],li;

bool vis[maxn];

mapnum;

queueq;

void addedge(int start,int end,int value)

void init()

bin[0]=1;

for (int i=1;i<=31;i++) bin[i]=bin[i-1]<<1;

init();

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

li=0;

for (int i=0;i<4;i++)

for (int k=1;k

}spfa(k);

} ans=inf;cho[0]=-1;

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

dfs1(1,i,0);

cout<

return 0;

}

計蒜客 2019 ICPC 南昌邀請賽

目錄 f.sequence 線段樹 單點更新 區間查詢 g.winner 思維 j.prefix 字典樹 k.a good game 樹狀陣列 貪心 題意 定義給定 操作1 格式為0 x y,把ax改為y 操作2 格式為1 x y,求f x,y 分析 不難發現,f l,r 可由以下項異或得到 1 r...

2019ICPC南昌邀請賽A (斯坦納樹)

大致題意 給定n個點,m條邊,給定4對點,要求將這4對點對應聯通,重複用邊只要算一次。思路還是先跑乙個斯坦納樹森林,然後合理狀態有所不同,需要一一對應,也就是對應位置必須同時出現。但是有個坑點,4對點中可能有的點會重複出現,所以對於狀態點用vector存一下相應的圖上點。具體避免方式看 這種模板題,...

2023年南昌ICPC邀請賽網路賽

a 直接跑一下 printf 6 n28 n496 n8128 n33550336 n k 跑一下會出來類似下面的規律 然後四個作為乙個迴圈節,推一下 j 樹剖加主席樹模板 i 單調棧跑一下兩邊最小值的問題,然後st表預處理字首和,接著列舉最小值,找到最遠做貢獻的區間後,分類討論 如果是正數,那就後...