POJ 2421 解題報告

2021-07-03 02:50:01 字數 1555 閱讀 9418

這道題還是求最小生成樹。兩個村莊connected的定義就是一般意義上的connected,只不過是通過「遞迴」地定義的:要不直接有路相連,要不鄰接的村莊能「connect」。這就是最小生成樹的目的:所有點都是聯通的,但是又是最小的。

因而常見的兩種最小生成樹演算法:prim和kruskal都可以用。我這裡用的是kruskal,因為之前的1251,1258都已經用過。直接用的之前的**。

這道題不同之處是規定有些路(無論遠近)已經包含在最小生成樹裡面了。這裡的處理辦法就是把這些路的距離設為0,這樣求最小生成樹的時候必然會先考慮完這些路再(從小到大)考慮別的。

thestoryofsnow

2421

accepted

264k

79ms

c++

/* 

id: thestor1

lang: c++

task: poj2421

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

void makeset(const int n, std::vector&parent, std::vector&rank)

}int find(int u, std::vector&parent)

return parent[u];

}void union_set(int u, int v, std::vector&parent, std::vector&rank)

if (rank[ru] < rank[rv])

else if (rank[rv] < rank[ru])

else }

class edge

edge(int u, int v, int w) : u(u), v(v), w(w) {}

bool operator< (const edge &rhs) const

return this->u < rhs.u || (this->u == rhs.u && this->v < rhs.v);

}};int kruskal(const int n, std::vector&edges)

} return mst;

}int main() }

int q;

scanf("%d", &q);

for (int i = 0; i < q; ++i)

std::vectoredges(n * (n - 1) / 2);

int edgeno = 0;

for (int u = 0; u < n; ++u) }

assert (edgeno == n * (n - 1) / 2);

sort(edges.begin(), edges.end());

printf("%d\n", kruskal(n, edges));

return 0;

}

poj2421 最小生成樹

題目鏈結在這裡 題目大意 有n個村莊,每個村莊之間都有一定的距離,想建幾條路使得村莊之間相互連通,問所需要花費的最小代價是什麼。有的村莊之間是相互連通的 解題思路 相互連通的村莊之間的距離置為0,然後將所有村莊之間的距離放到堆裡,直接最小生成樹莽出來就完事了。如下 include include i...

poj解題報告 1328

不得不說,這題是讓我飽受折磨,畢竟第一次做貪心演算法,而且wa了好多次,幸好有學長的幫助,最終找到了問題所在,是在快排上是問題,double高位不可向int低位轉換,由於一開始強制轉換導致雖然樣例和其他的測試資料過了,但還是wa,現在改完了就對了,附上ac ps 這題通過率是22 真心不簡單 如下 ...

poj解題報告 2586

這題我是用的貪心演算法,其實不用也可以,列舉也能解決,因為情況不多。因為是每連續5個月必有虧損,而一年只有1 5,2 6,3 7,4 8 8 12共8種情況。現在設盈餘為s,虧損為d,可列出以下幾種情況。ssssdssssdss 4ssssddsssddss 3s 2d ssdddssdddss 2...