朱刘算法求最小树形图

Posted aininot260

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了朱刘算法求最小树形图相关的知识,希望对你有一定的参考价值。

有向图中点点连通边权之和最小

算法过程不研究了,以后能看懂再说。。

直接贴一道以前写过的题

Openjudge的题面是地震之后,实则为一道POJ题目

  1 #include<cstdio>  
  2 #include<iostream>  
  3 #include<cstring>  
  4 #include<cmath>  
  5 using namespace std;  
  6 const int maxn = 105;  
  7 const int INF = 0x7fffffff;  
  8 template<typename Type>  
  9 struct Directed_MST
 10 {  
 11     void init(int _n)
 12     {  
 13         n=_n;   
 14         ans = 0;  
 15         memset(vis, 0, sizeof(vis));  
 16         memset(inc, 0, sizeof(inc));  
 17         for(int i=0; i<=n; ++i)
 18         {  
 19             w[i][i] = INF;  
 20             for(int j=i+1; j<=n; ++j)  
 21                 w[i][j]=w[j][i]=INF;  
 22         }  
 23     }  
 24     void insert(int u, int v, Type _w)
 25     {  
 26         if(w[u][v]>_w) w[u][v] = _w;  
 27     }  
 28     Type directed_mst(int u)
 29     {    
 30         dfs(u);  
 31         for(int i=1; i<=n; ++i)  
 32             if(!vis[i]) { return -1; }  
 33         memset(vis, 0, sizeof(vis));  
 34         while(true)
 35         {    
 36             for(int i=1; i<=n; ++i)if(i!=u&&!inc[i])
 37             {  
 38                 w[i][i]=INF, pre[i] = i;  
 39                 for(int j=1; j<=n; ++j)if(!inc[j] && w[j][i]<w[pre[i]][i])
 40                 {  
 41                     pre[i] = j;  
 42                 }  
 43             }   
 44             int i;  
 45             for(i=1; i<=n; ++i)if(i!=u&&!inc[i])
 46             {  
 47                 int j=i, cnt=0;  
 48                 while(j!=u && pre[j]!=i && cnt<=n) j=pre[j], ++cnt;  
 49                 if(j==u || cnt>n) continue;  
 50                 break;  
 51             }                 
 52             if(i>n)
 53             {    
 54                 for(int i=1; i<=n; ++i)if(i!=u && !inc[i]) ans+=w[pre[i]][i];  
 55                 return ans;  
 56             }     
 57             int j=i;  
 58             memset(vis, 0, sizeof(vis));  
 59             do{  
 60                 ans += w[pre[j]][j], j=pre[j], vis[j]=inc[j]=true;  
 61             }while(j!=i);  
 62             inc[i] = false; 
 63             for(int k=1; k<=n; ++k)if(vis[k])
 64             {
 65                 for(int j=1; j<=n; ++j)if(!vis[j])
 66                 {
 67                     if(w[i][j] > w[k][j]) w[i][j] = w[k][j];  
 68                     if(w[j][k]<INF && w[j][k]-w[pre[k]][k] < w[j][i])  
 69                         w[j][i] = w[j][k] - w[pre[k]][k];  
 70                 }    
 71             }  
 72         }  
 73         return ans;        
 74     }  
 75     void dfs(int u)
 76     {  
 77         vis[u] = true;  
 78         for(int i=1; i<=n; ++i)if(!vis[i]&&w[u][i]<INF)
 79         {  
 80             dfs(i);  
 81         }  
 82     }   
 83     Type ans;
 84     int n; 
 85     int pre[maxn];
 86     bool vis[maxn];
 87     bool inc[maxn];
 88     Type w[maxn][maxn];
 89 };  
 90 Directed_MST<double>G;  
 91 double x[maxn],y[maxn];  
 92 double getDist(double x1,double y1,double x2,double y2
 93 )
 94 {  
 95     return sqrt(pow(x1-x2,2)+pow(y1-y2,2));  
 96 }  
 97   
 98 int main()
 99 {  
100     int n,m;  
101     while(~scanf("%d%d",&n,&m))
102     {  
103         G.init(n);  
104         for(int i=1; i<=n; ++i)  
105             scanf("%lf%lf",&x[i],&y[i]);  
106         for(int i=0; i<m; ++i)
107         {  
108             int a,b;  
109             scanf("%d%d",&a,&b);  
110             if(a==b)continue;  
111             G.insert(a,b,getDist(x[a],y[a],x[b],y[b]));  
112         }  
113         double ans = G.directed_mst(1);  
114         if(ans < 0) puts("NO");  
115         else printf("%.2f
", ans);  
116     }  
117     return 0;  
118 } 

裸的最小树形图

以上是关于朱刘算法求最小树形图的主要内容,如果未能解决你的问题,请参考以下文章

最小树形图:朱刘算法

定根最小树形图 朱刘算法 luogu P4716

“Hdu4966” GGS-DDU - 最小树形图/朱刘算法

Directed_MST 最小树形图

最小树形图

bzoj2753: [SCOI2012]滑雪与时间胶囊