十二橋問題

2021-09-29 11:23:42 字數 1744 閱讀 7301

筆者最開始沒看見(k<=12),明明題名都給得如此清楚了,。好了,回到正題,k如此的小,我們可以考慮一下狀壓dp,方程式也很好想,根據每一條邊去推就好了。問題是如果每次需要用兩個端點距離時都去找一遍的話很有可能炸,我們可以考慮在開始時將所有端點都spfa一遍,加上1,最多也只會spfa25次。有的大佬優化到了13次,如indra,具體說就是將每條邊的中點為單位,去spfa。

感謝出題人沒卡spfa,儘管某些大佬用dijk也過了。

#include#include#include#include#include#include#include#include#include#include#define maxm 400005

#define maxn 50005

using namespace std;

typedef long long ll;

const ll inf=0x7f7f7f7f7f7f;

mapmp;

int n,m,k,tot;

int to[maxm],from[maxm],nxt[maxm];

int bbh[maxm];

ll paid[maxm];

int head[maxn],toti;

ll dp[30][5005],ans;

ll w[30][30],dis[maxn];

bool vis[30],inque[maxn];

queueq;

#define gc() getchar()

templateinline void read(_t &x)

while(s>='0'&&s<='9')

x*=f;

}void addedge(int u,int v,ll w)

void spfa(int x)

}for(int i=1;i<=2*k;i++)

w[mp[x]][mp[from[i]]]=dis[from[i]];

w[mp[x]][mp[1]]=dis[1];

}//標準的模板

int main()

//bbh用來存當前邊編號

for(int i=1;i<=2*k;i++)

if(!mp[from[i]])

mp[from[i]]=++tot;//記錄下需要用來dp的節點,離散化

if(!mp[1]) mp[1]=++tot;

for(int i=1;i<=2*k;i++)

if(!vis[mp[from[i]]])

spfa(from[i]),vis[mp[from[i]]]=true;//更新每個節點距離

if(!vis[mp[1]]) spfa(1);

for(int i=1;i<(1

dp[j][i]=inf;

for(int i=1;i<=2*k;i++)

dp[mp[to[i]]][1<<(bbh[i]-1)]=w[mp[1]][mp[from[i]]]+paid[i];//初始化

for(int i=1;i<(1

}ans=inf;int s=(1

ans=min(dp[mp[to[i]]][s]+w[mp[to[i]]][mp[1]],ans);//統計答案,記得連與1的邊

printf("%lld",ans);

return 0;

}

牛客 十二橋問題 (最短路 狀態壓縮)

小多所在的城市可以看成是有n個點m條邊的無向圖 結點從1標號 每條邊有乙個距離di,其中有k條邊是小希特別想走過的k座大橋。小多和小希現在呆在1號結點,請你幫小多規劃一條最短路線,使得小多和小希能從當前位置出發,並經過這k座橋,最後回到結點1。第一行輸入三個數n,m,k,分別表示結點數目,邊數和小希...

《演算法》七橋問題

萊昂哈德 尤拉在1735年提出,並沒有方法能圓滿解決這個問題,他更在第二年發表在 柯尼斯堡的七橋 中,證明符合條件的走法並不存在,也順帶提出和解決了一筆畫問題 1 這篇 在聖彼得堡科學院發表,成為圖論史上第一篇重要文獻。尤拉把實際的抽象問題簡化為平面上的點與線組合,每一座橋視為一條線,橋所連線的地區...

7 3 七橋問題

小知識 尤拉迴路 如果圖g中的乙個路徑包括每個邊恰好一次,則該路徑稱為尤拉路徑。如果乙個迴路是尤拉路徑,則稱為尤拉迴路。具有尤拉迴路的圖稱為尤拉圖 簡稱e圖 具有尤拉路徑但不具有尤拉迴路的圖稱為半尤拉圖。所有頂點的度均為偶數的任何連通圖必然有尤拉迴路。哥尼斯堡是位於普累格河上的一座城市,它包含兩個島...