題目:
題目描述
長假過後,迷宮設計大師必須完成他的工作。旅遊公司給他一張矩形的地圖。地圖由n*m個小方塊組成。旅遊公司將把一對夫婦放在迷宮中的兩個不同的小方塊上,讓他們互相尋找。
原本的地圖上是空曠曠的一片,大師要做的就是在一些小方塊之間建造一些牆從而把地圖變成迷宮。
建造的迷宮有乙個條件,無論這對夫妻出現在何處,他們之間只有且僅有一條路。
這對他來說並不困難,但他是乙個善解人意的人。
他也知道在兩個相鄰廣場之間建造每面牆的成本是不同的。
所以他想設計乙個迷宮,讓旅遊公司花費最少的錢來建造它並滿足上訴條件。
建成迷宮後,你得到了 q 個詢問包含夫妻兩人將被放置的位置資訊。
你需要弄 清楚它們之間最短路徑的長度(乙個小方格為乙個單位)。
輸入輸出格式
輸入格式:
輸入的第一行包含兩個整數 n和m。
接下來輸入的 n×m 行給出迷宮中每個小方塊的資訊,它們的資訊按順序輸入, 輸入順序為 (1,
1),(
1,2)
,(1,
3)…(
1,m)(2
,1)(
2,2)
(2,3
)…(3,1
)……(n,m)
每行包含兩個字元 d 和 r 和兩個整數,d 後面的整數代表建造該小方格下邊的牆的花費,r 後面的整數代表建造該小方格右邊的牆的花費。
如果邊是邊界,缺少的路徑將被替換為 x 0。
下一行包含乙個整數 q 表示有q個詢問。
接下來q 行,每一行兩個整數對(x1,y1)
(x2,y2)代表夫妻兩人的位置座標。
輸入資料保證滿足條件的只有一種迷宮(即答案唯一)。
輸出格式:
對於每個問題,輸出一行,其中乙個整數表示兩個給定方塊之間最短路徑的長度。
輸入輸出樣例
輸入樣例#1: 33
d 1 r 9
d 7 r 8
d 4 x 0
d 2 r 6
d 12 r 5
d 3 x 0
x 0 r 10
x 0 r 11
x 0 x 031
1331
2322
231輸出樣例#1: 42
2說明對於30
%的資料:
0<=n,m<=
5對於100
%的資料:0
<=n,m<=
500
思路:
最大生成樹+lca。
把加邊改為刪邊,然後跑最小生成樹求出路徑。
再在路徑上跑lca求最短距離。
注意:n,m不要弄反,邊的最大值為500000。
**:
#include
using
namespace std;
#define read(x) scanf("%d",&x)
#define maxn 500000
struct edge
edge
(int xx,
int yy,
int zz)
bool
operator
<
(const edge& oth)
const};
int n,m,cc=0;
edge e[maxn+5]
;int
getid
(int x,
int y)
void
readin()
}}}vector<
int> tr[maxn+5]
;int fa[maxn+5]
;int
find
(int x)
void
kruskal()
return;}
int d[maxn+5]
,anc[maxn+5]
[30];
void
dfs(
int x,
int fa)
for(
int i=
0;i.size()
;i++)}
intfindlca
(int x,
int y)
if(x==y)
return x;
for(
int i=
25;i>=
0;i--
)return anc[x][0
];}int
main()
return0;
}
膜你賽 ROAD (跑路)
小a的家到公司的路可以看做乙個有向圖,小a家為點1,公司為點n,每條邊長度均為一千公尺。假設小a每秒鐘可以跑2 k千公尺 k是任意數 當然,所以總跑路長度不能超過maxlongint千公尺。問最少需要幾秒才能到公司。資料保證1到n至少有一條路徑。第一行兩個整數n,m,表示點的個數和邊的個數。接下來m...
2018 10 30 膜你賽 火柴
題目 題目描述 p同學總共有k根火柴,分別放在擺成一列的n個火柴盒內,保證k是n的倍數。p同學想要每個火柴盒都有相同數目的火柴,每次他可以從乙個火柴盒中拿一根火柴放到相鄰的火柴盒中。他想知道他最少要移動多少次。輸入輸出格式 輸入格式 第一行乙個整數n,表示火柴盒數。第二行n個整數a 1,a 2,a ...
2018 10 30 膜你賽 咒語
題目 題目描述 亮亮夢到自己來到了魔法城堡,但一扇巨大的石門阻攔了他通向城堡內的路。正當他沮喪之際,突然發現門上有一處機關,機關上有一張很長的紙條。亮亮拿起紙條的一端,只見上面寫著開啟機關的方法 開啟機關需要唸動符咒,咒語是一串長為 l 的由 0 和 1 組成的字串。在這張長紙條上列了 n 個 長為...