小多所在的城市可以看成是有n個點m條邊的無向圖(結點從1標號),每條邊有乙個距離di,其中有k條邊是小希特別想走過的k座大橋。
小多和小希現在呆在1號結點,請你幫小多規劃一條最短路線,使得小多和小希能從當前位置出發,並經過這k座橋,最後回到結點1。
第一行輸入三個數n,m,k,分別表示結點數目,邊數和小希特別想走過的大橋數目。
隨後m行,第i行三個整數ui,vi,di表示從ui到vi有一條距離為di的邊。
其中前k條邊即為小希想去的大橋。
輸出一行,乙個整數,表示滿足條件的最短距離的路徑長度。
示例1輸入
3 4 2
2 3 5
2 2 10
1 2 1
3 1 4
輸出20
說明小希按線路1->2->2->3->1,分別花費1,10,5,4,共計20。
備註:對於100%的資料,整張圖聯通,di≤1000000000。
分析為什麼我覺得記錄牛客的題解像是在蹭熱度一般的罪惡
發現$k$還挺小的,所以考慮來一手全排列狀態壓縮,01表示一座橋是否走過
由於是最短長度,對於1號節點和所有橋的兩個端點都要求一次最短路
dp的時候可以不用管具體是怎麼走的,只管用最短路求出的路徑無腦轉移
雖然這樣可能會出現一些奇怪的轉移和狀態,但因為最優方案肯定是走最短路徑,所以我們一定會統計到最優方案的答案並把它存下來
但是如果直接壓縮進行$dp$,就不知道誰跟誰相連,更不知道當前狀態該怎麼去更新下乙個狀態
誰跟誰相連並不重要,重要的是應該知道當前的路徑末端是誰,所以$dp$狀態中應該加入當前的末端是誰
所以設$dp[i][s]$表示以1,i為兩個端點形成的走過邊的情況為s的鏈的最短長度,其中i為最後經過的那個橋的乙個端點
列舉最後走過的橋,下一座走過的橋,還有從哪個端點走到哪個端點,就可以轉移狀態了
感謝出題人不卡spfa
code
#include#include#include
#include
using
namespace
std;
const
int maxn=50005
;const
int maxm=200005
;long
long d[maxn],dis[30][maxn],l[maxm][5];queueq;long
long dp[30][30005
],ans;
int n,m,k,ecnt,info[maxn],inq[maxn],nx[maxm<<1],v[maxm<<1],w[maxm<<1
];void add(int u1,int v1,int w1)
void spfa(int
x) }
}int
main()
memset(dp,
0x7f,sizeof dp);ans=dp[0][0
];
for(int i=1;i<=k;i++)for(int j=0;j<=1;j++)
int i=(1
<
);
for(int i=1;i<=k;i++)
for(int nw=1;nw)}}
for(int i=1;i<=k;i++)ans=min(ans,min(dp[i*2-1][i]+d[l[i][0]],dp[i*2][i]+d[l[i][1
]]));
printf(
"%lld\n
",ans);
}
牛客14369之最短路(SPFA模板)
簡單暴力的題目要求 給定乙個有n個頂點 從1到n編號 m條邊的有向圖 其中某些邊權可能為 負,但保證沒有負環 請你計算從1號點到其他點的最短路。第一行兩個整數n,m。接下來的m行,每行有三個整數u,v,l,表示u到v有一條長度為l的邊。共n 1行,第i行表示1號點到i 1號點的最短路。3 3 1 2...
牛客 D 炫酷路途(貪心 最短路)
題目描述 小希現在要從寢室趕到機房,路途可以按距離分為n段,第i個和i 1個是直接相連的,只需要一秒鐘就可以相互到達。炫酷的是,從第i個到第i 2 pi 2 p個也是直接相連的 其中p為任意非負整數 只需要一秒鐘就可以相互到達。更炫酷的是,有k個傳送法陣使得某些u,v之間也是直接相連的,只需要一秒鐘...
牛客網機試題 最短路徑(並查集)
n個城市,標號從0到n 1,m條道路,第k條道路 k從0開始 的長度為2 k,求編號為0的城市到其他城市的最短距離 第一行兩個正整數n 2 n 100 m m 500 表示有n個城市,m條道路 接下來m行兩個整數,表示相連的兩個城市的編號n 1行,表示0號城市到其他城市的最短路,如果無法到達,輸出 ...