XSY3370 道路建設 最短路

2022-03-25 17:28:02 字數 1622 閱讀 8007

有乙個完全圖,邊有邊權。

對於每個 \(i\),求一棵生成樹,使得( \(\sum_^n\)

\(j\) 到 \(i\) 的路徑上邊權最小值) 最小。

\(n\leq 2000,w\leq ^9\)

記最小的邊權 \(w\),這條邊的乙個端點為 \(s\)。

那麼 \(i\) 號點對應的生成樹就是從 \(i\) 到 \(s\) 的一條路徑,然後經過邊權最小的邊,再連向所有點。

可以發現 \(i\) 到 \(s\) 的路徑上除了最後一條邊之外的邊權是遞減的。而且每條邊的邊權 \(<\) 後面所有邊(除了最後一條邊)的邊權和。所以深度會 \(\leq o(\log w)\)。

直接從每個點開始跑最短路就可以做到 \(o(n^2\log w)\) 。

從 \(s\) 開始向每個點跑最短路就可以在 \(o(n^2)\) 內解決這道題了。

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

using std::min;

using std::max;

using std::swap;

using std::sort;

using std::reverse;

using std::random_shuffle;

using std::lower_bound;

using std::upper_bound;

using std::unique;

using std::vector;

typedef long long ll;

typedef unsigned long long ull;

typedef double db;

typedef long double ldb;

typedef std::pairpii;

typedef std::pairpll;

void open(const char *s)

void open2(const char *s)

int rd()dowhile((c=getchar())>='0'&&c<='9');return b?-s:s;}

void put(int x)static int c[20];int t=0;while(x)while(t)putchar(c[t--]+'0');}

int upmin(int &a,int b)return 0;}

const int n=2010;

int a[n][n];

int b[n];

ll s[n];

int n;

int mi[n];

int main()

b[t]=1;

s[t]=0;

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

if(i!=t)

s[i]=min(a[t][i]-w,2*mi[i]-2*w);

for(int i=1;ifor(int i=1;i<=n;i++)

printf("%lld\n",s[i]+(ll)(n-1)*w);

return 0;

}

xsy2304 哈 最短路

題目大意 有乙個 n 個點,m 條有向邊的圖,有 q 組詢問。每次詢問 從 a 到 b 經過不超過 c 條邊,且依次經過的邊邊權遞增,問最短路為多少,無解輸出 1。資料範圍 n 150 m 5000 q 1000 我場上並沒有去想正解,打了個spfa居然獲得 90pts 好成績。首先對於經過不超過 ...

XSY1162 鬼計之夜 最短路

給你乙個 n 個點 m條邊的有向圖,有 k 個關鍵點。求一條最短的從乙個關鍵點到另乙個關鍵點的路徑。n,m,k 100000跑k 2 次最短路顯然會tle 考慮兩個不同的數有什麼可以利用的性質。其中會有至少乙個二進位制為不同!所以可以列舉所有二進位制位,從 0 的那邊向 1的那邊跑最短路,再從 1 ...

XSY2679 修牆 最短路

有乙個 n 1 m 1 的網格,每條邊都有乙個邊權。有一些格仔是城市。你要用乙個環圈住所有城市,要求環上所有邊的邊權和最小。重合的邊邊權算多次。保證左上角 1 1 一定有乙個城市。n,m 400 觀察到左上角一定有乙個城市。首先求出每個城市左上角到 0 0 的最短路,那麼這個圈肯定不會經過最短路。如...