HDU2988(Kruskal水),hdu2988kruskal水
其實現在更新部落格,寫題解的興緻已經不高了,明天是網賽第一場,希望能夠順利。
寫這篇文章是因為我打算把基本的演算法都寫一遍,以便筆試面試什麼的。
從圖論開始,對圖論有一種說不出的喜歡。
HDU2988是Kruskal水題,為什麼用Kruskal,因為點多200000,邊少,稀疏圖呢。
Kruska的演算法是十分簡單的,就是貪心,從最小權值開始遍曆,通過並查集來確認加入這條邊是否會形成迴路,如果沒有則加入到最小產生樹的邊集中,最後一定會形成最小產生樹(MST)。
下面是code
/*********************************************************** > OS : Linux 3.13.0-24-generic (Mint-17) > Author : yaolong > Mail : dengyaolong@yeah.net > Time : 2014年09月04日 星期四 07:52:04 **********************************************************/#include<iostream>#include<cstdio>#include<string>#include<vector>#include<algorithm>using namespace std;#define MAXN 220000int f[MAXN];int find(int x){ if ( x == f[x] ) { return x; } return f[x] = find(f[x]);}struct Edge{ int u, v, w; Edge(){} Edge(int uu, int vv ,int ww):u(uu) ,v(vv), w(ww){} bool operator < ( const Edge &e )const { return this->w < e.w ; }};int main(){ vector <Edge> ve; int u, v, w; int n, m; while( scanf( "%d%d" ,&n ,&m ) ,n || m ) { ve.resize(m); int ans=0; for(int i = 0; i < n; i++ ) { f[i]= i; } while( m-- ) { scanf("%d%d%d",&u, &v, &w); ans+=w; ve[m]=Edge(u, v, w); } sort(ve.begin(),ve.end()); for(vector<Edge>::iterator itr = ve.begin();itr != ve.end(); ++itr ) { int fu = find( (*itr).u ),fv = find( (*itr).v ); if ( fu !=fv) { f[fu] = fv; ans -= (*itr).w; } } printf("%d\n",ans); } return 0;}
hdu 1875 最小產生樹(Kruskal)CE 瞭解釋,大牛
把distance函數換個名,這個函數被定義過了
參考資料:www.cplusplus.com/...tance/