欧几里德 平面最小生成树算法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了欧几里德 平面最小生成树算法相关的知识,希望对你有一定的参考价值。

小弟要做个算法方面的毕业论文
有没人详细介绍该算法?特别是三角分化那快。
对时间复杂度做详细的分析。
如果有C++或者VC源文件就太好了。

谢谢啊!!!!

参考技术A 欧几里德算算法gcd(a,b)=ax+by:
int ext_gcd(int a,int b,int& x,int& y)
int t,ret;
if (!b)
x=1,y=0;
return a;

ret=ext_gcd(b,a%b,x,y);
t=x,x=y,y=t-a/b*y;
return ret;


最小生成树(Prim算法):
//无向图最小生成树,prim算法,邻接阵形式,复杂度O(n^2)
//返回最小生成树的长度,传入图的大小n和邻接阵mat,不相邻点边权inf
//可更改边权的类型,pre[]返回树的构造,用父结点表示,根节点(第一个)pre值为-1
//必须保证图的连通的!
#define MAXN 200
#define inf 1000000000
typedef double elem_t;

elem_t prim(int n,elem_t mat[][MAXN],int* pre)
elem_t min[MAXN],ret=0;
int v[MAXN],i,j,k;
for (i=0;i<n;i++)
min[i]=inf,v[i]=0,pre[i]=-1;
for (min[j=0]=0;j<n;j++)
for (k=-1,i=0;i<n;i++)
if (!v[i]&&(k==-1||min[i]<min[k]))
k=i;
for (v[k]=1,ret+=min[k],i=0;i<n;i++)
if (!v[i]&&mat[k][i]<min[i])
min[i]=mat[pre[i]=k][i];

return ret;
参考技术B 太高深了 参考技术C 去看Winter Camp 2006 王栋的论文
可以做到n log n本回答被提问者采纳

uva 1151Buy or Build(图论 最小生成树)

题意:平面上有N个点(1≤N≤1000),若要新建边,费用是2点的欧几里德距离的平方。另外还有Q个套餐,每个套餐里的点互相联通,总费用为Ci。问让所有N个点连通的最小费用。(2组数据的输出之间要求有换行)

解法:利用二进制枚举套餐,时间复杂度是O(2QN2+N2logN)。关于时间复杂度,枚举:二进制枚举为2Q,Kruskal为ElogE≈E≈N2;边排序:ElogE≈E≈N2。总的相加。

紫书上提到一个优化:不加任何套餐跑一遍MST(最小生成树),没有选的边便删除掉,因为以后加了套餐之后也选不到它。

理解有点困难:由于Kruskal算法中不会进入MST的边是那些两端属于同一个连通分量的边,那么套餐里的点互相连通,相当于在原先MST的图上另外加了几条权值为0的边。这时可能超过N-1条边出现环,那么我们就要割掉权值最大的这个环里的边,留下较小的边。这样的MST就是除了套餐必要的费用之外的权值和最小的了。

P.S.如果比赛时想不明白,那就只能对拍了!

P.P.S.但我不知道为什么优化无论加不加时间都差不多,明明优化使时间复杂度变为了O(2QN+N2logN),2Q≈103,N=103,logN≈10,理应由O(106)变为O(103)啊。

下面附上我的加了优化的代码——

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<cstring>
  4 #include<iostream>
  5 #include<algorithm>
  6 using namespace std;
  7 const int N=1010,M=(int)1e6+10,Q=10,X=3010,D=(int)2e6+10;
  8 typedef long long LL;
  9 
 10 int n,q,m;
 11 int fa[N];
 12 struct hp{int c,t;int s[N];}b[Q];
 13 struct vert{int x,y;}a[N];
 14 struct edge{int x,y,d;}e[M];
 15 
 16 LL mmin(LL x,LL y) {return x<y?x:y;}
 17 int sq_dist(int i,int j) {return (a[i].x-a[j].x)*(a[i].x-a[j].x)+(a[i].y-a[j].y)*(a[i].y-a[j].y);}
 18 void ins(int id,int x,int y,int d) {e[id].x=x,e[id].y=y,e[id].d=d;}
 19 bool cmp(edge x,edge y) {return x.d<y.d;}
 20 int ffind(int x)
 21 {
 22     if (fa[x]!=x) fa[x]=ffind(fa[x]);
 23     return fa[x];
 24 }
 25 LL MST()
 26 {
 27     int i,t=0;
 28     int cnt=0;//0
 29     LL ans=0;
 30     sort(e+1,e+1+m,cmp);
 31     for (i=1;i<=n;i++) fa[i]=i;
 32     for (i=1;i<=m;i++)
 33     {
 34       int x=e[i].x,y=e[i].y;
 35       int xx=ffind(x),yy=ffind(y);
 36       if (xx!=yy)
 37       {
 38         fa[xx]=yy;
 39         cnt++,ans+=e[i].d;
 40         e[++t]=e[i];
 41         if (cnt==n-1) break;
 42       }
 43     }
 44     m=t;
 45     return ans;
 46 }
 47 LL MST_2(int cnt)
 48 {
 49     int i;
 50     LL ans=0;
 51     for (i=1;i<=m;i++)
 52     {
 53       int x=e[i].x,y=e[i].y;
 54       int xx=ffind(x),yy=ffind(y);
 55       if (xx!=yy)
 56       {
 57         fa[xx]=yy;
 58         cnt++,ans+=e[i].d;
 59         if (cnt==n-1) break;
 60       }
 61     }
 62     return ans;
 63 }
 64 int main()
 65 {
 66     int T,i,j,k;
 67     scanf("%d",&T);
 68     while (T--)
 69     {
 70       scanf("%d%d",&n,&q);
 71       for (i=1;i<=q;i++)
 72       {
 73         scanf("%d%d",&b[i].t,&b[i].c);
 74         for (j=1;j<=b[i].t;j++)
 75           scanf("%d",&b[i].s[j]);
 76       }
 77       for (i=1;i<=n;i++)
 78         scanf("%d%d",&a[i].x,&a[i].y);
 79       m=0;
 80       for (i=1;i<=n;i++)
 81        for (j=i+1;j<=n;j++)
 82          ins(++m,i,j,sq_dist(i,j));
 83      
 84       LL ans=MST();
 85       for (i=0;i<(1<<q);i++)//bracelet
 86       {
 87        for (j=1;j<=n;j++) fa[j]=j;
 88        int cnt=0,h=0;
 89        for (j=1;j<=q;j++)
 90         if (i&(1<<(j-1)))
 91         {
 92          h+=b[j].c;
 93          for (k=2;k<=b[j].t;k++)
 94          {
 95            int x=b[j].s[1],y=b[j].s[k];
 96            int xx=ffind(x),yy=ffind(y);
 97            if (xx!=yy) fa[xx]=yy,cnt++;
 98          }
 99         }
100        ans=mmin(ans,h+MST_2(cnt));
101       }
102       printf("%lld\n",ans);
103       if (T) printf("\n");
104     }
105     return 0;
106 }

 

以上是关于欧几里德 平面最小生成树算法的主要内容,如果未能解决你的问题,请参考以下文章

uva 1151Buy or Build(图论 最小生成树)

图的最小生成树算法?

算法最小乘积生成树 & 最小乘积匹配 (HNOI2014画框)

图的最小生成树算法(Prim和Kruskal)

经典树与图论(最小生成树、哈夫曼树、最短路径问题---Dijkstra算法)

最小生成树 普里姆算法有问