題目描述:
有乙個 m 行 n 列的點陣,相鄰兩點可以相連。
一條縱向的連線花費乙個單位,一條橫向的連線花費兩個單位。
某些點之間已經有連線了,試問至少還需要花費多少個單位才能使所有的點全部連通。
輸入格式
第一行輸入兩個正整數 m 和 n。
以下若干行每行四個正整數 x1,y1,x2,y2,表示第 x1 行第 y1 列的點和第 x2 行第 y2 列的點已經有連線。
輸入保證|x1−x2|+|y1−y2|=1。
輸出格式
輸出使得連通所有點還需要的最小花費。
資料範圍
1≤m,n≤1000
0≤已經存在的連線數≤10000
輸入樣例:
2 2
1 1 2 1
輸出樣例:
3
分析:
本題與上一題很類似,圖中都是有兩類邊,處理方法也很類似,考察的其實是想象能力。圖中的點是m * n的點陣,連線縱向的兩點花費1個單位,連線橫向的兩點消耗2個單位。我們其實並不需要顯式的用乙個結構體陣列或者鄰接矩陣去儲存這個圖,因為點陣是極具規律性的,自左而右,自上而下點m * n個點依次編號為1到m * n。在讀取已有的連線時,獲取這兩個點的編號,連線這兩點即可。後面要考慮的是如何連線剩下的點?
既然連線縱向邊的消耗小,我們自然是先列舉縱向邊,再列舉橫向邊,按順序嘗試加入到並查集中。如何列舉縱向邊,點陣中的縱向邊是點i和點i + n的連線,其中i從1到(m - 1) * n。橫向邊則是i和i + 1的連線,當遍歷到編號為n的倍數的點時跳過即可。具體實現見**:
#include #include #include using namespace std;
const int n = 1005;
int n,m,fa[n * n];
int find(int x)
int main()
int c1 = m * n - n,c2 = c1 + n;
for(int i = 1;i <= c1;i++)
for(int i = 1;i <= c2;i++)
cout
}
Fzoj1616連線格點
fzoj1616連線格點 題目描述 有乙個m行n列的點陣,相鄰兩點可以相連。一條縱向的連線花費乙個單位,一條橫向的連線花費兩個單位。某些點之間已經有連線了,試問至少還需要花費多少個單位才能使所有的點全部連通?輸入 第1行 輸入兩個正整數m和n。以下若干行每行四個正整數x1 y1 x2 y2,表示第x...
CCF 1394(連線格點)
題目鏈結 思路 並查集 貪心。將二維壓縮成一維,如果有連線可以看作他們是乙個祖先 也可以說是親戚 如果沒有連線則把他們連在一起,先豎再橫,因為豎的代價更低。include define r i,a,b for int i a i b i using namespace std int f 10000...
六 連線模式 1) 連線簡介
可以借用 sql 的連線來解釋 假設 表a 表b 內連線 a.name b.name 儲存共有的相同值屬性 外連線 左外連線 以 外來鍵表a 左 屬性為基準。包含a屬性整列。b屬性符合a屬性值的存入,其餘b屬性被置為 null。右外連線 以 外來鍵表b 右 屬性為基準。包含b屬性整列。b屬性符合a屬...