GJGHFD的傳送門 題解 Floyd DP

2022-06-18 13:12:15 字數 2995 閱讀 8133

​ 給定一張 \(n\) 個點 \(m\) 條邊的連通圖,圖中每條邊都有乙個非負邊權,點的編號從 1 開始. 現在你有 \(k\) 個任務,第 \(i\) 個任務需要你先到達點 \(a_i\), 然後到達點 \(b_i\). 你需要依次完成這 \(k\) 個任務. 初始時你在 1 號點.

​ 現在你手裡有一把槍,當你在 \(u\) 號點朝地上開槍時,\(u\) 上就會建立乙個傳送門. 開槍消耗的時間可以忽略不計. 如果你在 \(u\), \(v\) 兩點都建立了傳送門,那麼你就可以在這兩點間不計消耗地任意傳送(你可以將其視作圖中加入了一條連線 \(u, v\) 且邊權為 0 的邊).

​ 遺憾的是,這張圖中同時只能存在 2 個傳送門. 因此當圖中存在了 2 個傳送門,且你需要再建立乙個傳送門時,你必須先選擇乙個已經建立的傳送門並關閉它. 關閉傳送門的消耗同樣是忽略不計的,並且你可以關閉處在任

意位置的傳送門,與你當前所在的位置無關.

​ 請求出完成這 \(k\) 個任務最少需要走過的距離.

​ 第一行三個整數 \(n, m, k\) ,分別代表圖中點的個數、邊的條數、任務的個數.

​ 接下來 \(m\) 行,每行三個整數 \(u, v, w\) ,表示圖中有一條連線 \(u, v\) ,且邊權為 \(w\) 的邊.

​ 接下來 \(k\) 行,每行兩個整數 \(a_i\), \(b_i\) ,表示第 \(i\) 個任務需要到達的兩個點.

​ 輸出一行乙個整數表示答案.

5 4 2

1 2 1

2 3 1

3 4 1

4 5 1

1 52 4

5
6 10 3

1 1 3

3 1 1

6 2 3

1 6 10

4 1 1

3 1 2

5 6 9

5 4 10

6 3 4

3 4 4

3 53 6

6 5

16
​ 對於\(30\%\)的資料,\(1 \leq n,k \leq 50\)

​ 另有\(30\%\)的資料,\(m=n-1\)

​ 對於\(100\%\)的資料,\(1 \leq n, k\leq 300,1 \leq m \leq 40000,0 \leq w \leq 10^9\)

​ 時間限制: \(1s\)

​ 空間限制: \(512m\)

​ 經過觀察我們發現n很小,因此先跑一遍floyd預處理出兩兩之間的最短路。

​ 然後我們再觀察傳送門的性質,可以發現,雖說有兩個傳送門,但實際上可以看作是乙個傳送門,然後你從任意乙個點都能到達傳送門所在的那個點(只需把另乙個傳送門放到你所在的點即可)。

​ 其次,所謂的\(k\)個任務是假的,其實就是\(k\times2\)個任務,每次從上乙個點到達這乙個點。

​ 於是我們考慮設\(f[i][j]\)表示完成前\(i\)個任務,當前有乙個傳送門在\(j\)的最優方案路徑長。(\(1\leq i \leq k \times 2,1 \leq j \leq n\))

​ 考慮轉移(x表示當前任務要到達的點,now表示上乙個任務要到達的點(now初始化為1)):

​ 1.\(f[i][j]=f[i-1][j]+min(dis[j][x],dis[now][x]);\)

​ 若把傳送門設在\(j\)這個位置,可以是之前傳送門就在\(j\),於是我們可以傳送到\(j\)然後走到\(x\),或者直接從上一次到達的點走到\(x\).

​ 2.\(f[i][j]=f[i-1][k]+min(dis[j][k],dis[now][k])+min(dis[k][x],dis[j][x])\);

​ 不難理解,若之前傳送門在\(k\),那麼我們為了把傳送門設在\(j\)位置,可以先由\(now\)或\(k\)位置走到\(j\),設下傳送門,然後從\(j\)或\(k\)位置走到\(x\).

​ 最後輸出\(f[k][now]\)即可.

​ ps:我用的dp用了滾存優化空間( 實際沒必要 ),

​ **如下(馬蜂很醜,不喜勿噴)——

#include#define tp template#define ts template#define reg register

#define ri reg int

#define con const

#define ci con int&

#define i inline

#define w while

#define maxn 305

#define maxm 80005

#define inf 214748364998244353

#define ll long long

#define min(a,b) ((a)<(b)?(a):(b))

using namespace std;

int n,m,k,tot,fir[maxn],nxt[maxm],son[maxm],w[maxm];ll ans=inf,f[2][maxn],dis[maxn][maxn];

inline void add(int x,int y,int z)

class fileinputoutput

tp inline void read(t& x)

tp inline void write(t x,const char& ch)

inline void flush(void)

#undef tc

#undef pc

}f;int main()

k<<=1;int now=1;memset(f,63,sizeof(f));

f[0][1]=0;for(register int k=1,x,op=(k&1);k<=k;now=x,op^=1,k++)

} f.write(f[k&1][now],'\n');return f.flush(),0;

}

GJGHFD的排列 題解 DP

給定乙個長度為 n 的排列 p 1 p 2 p n 你可以做以下兩個操作之一 1.將 p 移到 p 1 之前,即 p 1 p 2 p n rightarrow p p 1 p 2 p p n 2.將 p 移到 p n 之後,即 p 1 p 2 p n rightarrow p 2 p 3 p p n...

解鎖 傳送門

linenoise c命令列處理工具 catch2 c 測試框架 quick start linenoise ng linenoise next generation c 命令列處理工具 yarn 快速 可靠 安全的node包依賴管理工具 pandoc pandoc安裝 使用 快速上手 autope...

JZOJ A組 傳送門

8102年,normalgod在glados的幫助下,研製出了傳送槍。但glados想把傳送槍據為己有,於是把normalgod扔進了一間實驗室。這間實驗室是一棵有n個節點的樹。現在normalgod在一號節點,出口也在一號節點,但為了開啟它,必須經過每乙個節點按下每個節點的開關,出口才能開啟。gl...