題目大意:有一系列的點,這些點中假如歐氏距離小於r就認為是同一類,注意a和b同一類,b和c同一類,那麼a和c就是同一類。
現在要在點集中鋪路,在一類中我們需要鋪路使得類中的點都連通,在不同類也需要通過路來把它們全部連起來,使得類和類之間能夠互相連線。約束:注意我們總的鋪路的距離要盡可能小。
最後輸出鋪路的距離。
思路:首先在類中最小生成樹,然後不同類之間也要做乙個最小生成樹,注意在不同類別中做最小生成樹的時候,那乙個類別是作為乙個節點(在這裡wa了一發 555)。注意:在這裡乙個類就是題意中的乙個state.
ac**:
#include #define maxn 1010
#define unvisited 0
#define visited 1
using namespace std;
double dist[maxn][maxn];
int n;
int r;
int flag[maxn];
vectorconpoi;
typedef vectorvi;
class disjoint_union_set
}bool cmp(pair> &fir, pair> &las)
int main()
//cerr<<"read complete"<> veccon;
for (int i = 0; itmp = veccon[i];
vector> > edges;
for (int j = 0; j<(int)tmp.size() - 1; j++)
}disjoint_union_set duset(n + 1);
sort(edges.begin(), edges.end(), cmp);
for (int j = 0; j<(int)edges.size(); j++)
}} //cerr<<"fir kruskal "<>> edges;
for (int i = 0; i<(int)veccon.size() - 1; i++) }}
assert(rx != -1);
pairp;
p = make_pair(rx, ry);
pair> p2;
p2.first = min_dist;
p2.second = p;
edges.push_back(p2);
}} //cerr<<"connected component dist"
disjoint_union_set dset(n + 1);
sort(edges.begin(), edges.end(), cmp);
for (int i = 0; i<(int)edges.size(); i++)
} printf("case #%d: %d %d %d\n", ca + 1, veccon.size(), (int)round(kruskalsum), (int)round(kruskalsum2));
} return 0;
}
kruskal 最小生成樹
include include 產生隨機數組用 include 同上 include using namespace std 1 帶權邊的類myarc class myarc bool operator const myarc arc myarc myarc int beginvex,int end...
最小生成樹Kruskal
最小生成樹有兩個特點,乙個是保證了所有邊的和是最小值,另乙個是保證了所有邊中的最大值最小。struct edge bool friend operator edge a,edge b 構邊 vectoredge int id max int mini void initial void input ...
最小生成樹(kruskal)
kruskal演算法 1 記graph中有v個頂點,e個邊 2 新建圖graphnew,graphnew中擁有原圖中相同的e個頂點,但沒有邊 3 將原圖graph中所有e個邊按權值從小到大排序 4 迴圈 從權值最小的邊開始遍歷每條邊 直至圖graph中所有的節點都在同乙個連通分量中 if 這條邊連線...