筆者最開始沒看見(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圖 具有尤拉路徑但不具有尤拉迴路的圖稱為半尤拉圖。所有頂點的度均為偶數的任何連通圖必然有尤拉迴路。哥尼斯堡是位於普累格河上的一座城市,它包含兩個島...