POJ1358 Agri-Net
生活随笔
收集整理的這篇文章主要介紹了
POJ1358 Agri-Net
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接
?
就是裸的最小生成樹,復習一下。
prim算法:
G=(V,E),V是點集,E是邊集
假設T=(U,TE)是最小生成樹。U,TE初始化為空
?
首先從V中任取一點 假設取V1,然后U={V1},只要U是V的真子集,就從那些一個端點在T中,一個端點在T外的邊中,找一條最短邊。一直下去,直到找到n-1條邊
?
找邊使用 堆優化,復雜度(ElogV) 鄰接表復雜度(V2)
?
1 #include<cstdio> 2 #include<vector> 3 #include<queue> 4 #include<cstring> 5 using namespace std; 6 const int maxn=110; 7 const int inf=0x3f3f3f3f; 8 9 struct node{ 10 int v,dis; 11 node(){} 12 node(int _v,int _dis){ 13 v=_v; 14 dis=_dis; 15 } 16 bool operator<(const node &b) const { 17 return dis>b.dis; 18 } 19 }; 20 21 int n,dis[maxn]; 22 vector<node> G[maxn]; 23 bool vis[maxn]; 24 25 void prim() { 26 int ans=0,num=0; 27 priority_queue<node> pq; 28 for(int i=0;i<n;i++) { 29 vis[i]=false; 30 dis[i]=inf; 31 } 32 pq.push(node(0,0)); 33 node f; 34 while(num<n&&!pq.empty()) { 35 do{ 36 f=pq.top(); 37 pq.pop(); 38 }while(vis[f.v]&&!pq.empty()); 39 if(!vis[f.v]) { 40 ans+=f.dis; 41 vis[f.v]=true; 42 num++; 43 for(int i=0;i<G[f.v].size();i++) { 44 int v=G[f.v][i].v; 45 if(!vis[v]) { 46 if(dis[v]>G[f.v][i].dis) { 47 dis[v]=G[f.v][i].dis; 48 pq.push(node(v,dis[v])); 49 } 50 } 51 } 52 } 53 } 54 if(num<n) printf("-1\n");//因為這里記錄的是點的個數。不是邊 55 else printf("%d\n",ans); 56 } 57 58 int main() { 59 while(~scanf("%d",&n)) { 60 memset(G,0,sizeof(G)); 61 for(int i=0;i<n;i++) { 62 for(int j=0;j<n;j++) { 63 int x; 64 scanf("%d",&x); 65 if(x) G[i].push_back(node(j,x)); 66 } 67 } 68 prim(); 69 } 70 }?
krusual算法:
將圖G中的邊按權值從小到大選取,使選取的不與生成樹構成回路。直到n-1條邊為止
判斷回路就用并查集搞一下。
?
1 #include<cstdio> 2 #include<vector> 3 #include<queue> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int maxn=110; 8 const int inf=0x3f3f3f3f; 9 10 int n; 11 struct Edge{ 12 int u,v,dis; 13 Edge(){} 14 Edge(int _u,int _v,int _dis) { 15 u=_u; 16 v=_v; 17 dis=_dis; 18 } 19 bool operator <(const Edge &b) const { 20 return dis<b.dis; 21 } 22 }; 23 24 vector<Edge> edge; 25 26 int fa[maxn]; 27 28 int Find(int x) { 29 if(fa[x]==-1) return x; 30 else return fa[x]=Find(fa[x]); 31 } 32 33 void Union(int x,int y) { 34 int fx=Find(x); 35 int fy=Find(y); 36 if(fx!=fy) { 37 fa[fx]=fy; 38 } 39 } 40 41 int main() { 42 while(~scanf("%d",&n)) { 43 memset(fa,-1,sizeof(fa)); 44 edge.clear(); 45 for(int i=0;i<n;i++) { 46 for(int j=0;j<n;j++) { 47 int x; 48 scanf("%d",&x); 49 if(x&&j<i) edge.push_back(Edge(i,j,x)); 50 } 51 } 52 sort(edge.begin(),edge.end()); 53 int num=0,ans=0; 54 for(int i=0;i<edge.size();i++) { 55 int u=edge[i].u,v=edge[i].v,dis=edge[i].dis; 56 if(Find(u)!=Find(v)) { 57 num++; 58 ans+=dis; 59 Union(u,v); 60 } 61 } 62 if(num==n-1) printf("%d\n",ans); 63 else printf("-1\n"); 64 } 65 }?
轉載于:https://www.cnblogs.com/ACMerszl/p/10667146.html
總結
以上是生活随笔為你收集整理的POJ1358 Agri-Net的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求组合数的O(n^2)和O(n)解法及模
- 下一篇: 2019年4月8日 1021. Remo