最小树形图

原创 2007年09月15日 19:43:00

 

吴文虎的图论算法上写的比较清楚

还有wywcqs博客上也有很详细的解说了

http://hi.baidu.com/wywcgs/blog/item/a1ce10f4a8fa366fdcc47462.html

写了下O(VE)版本的,uva 11183

Ranking Submission Run Time Language Submission Date
10 5923090 0.390 C++ 2007-09-17 14:16:18

 

//uva 11183
#include <cstdio>
#include 
<cstring>
#include 
<cmath>
#include 
<vector>
#include 
<algorithm>
using namespace std;

const int NMAX = 1500;
const int INF = 0x7f7f7f7f;
struct LINKT ...{
    
int ls;
    
int adj[NMAX];
    
void clear() ...{ls = 0;}
    
int operator [] (const int pos) ...{return adj[pos];}
    
int size() ...{return ls;}
    
void push_back(const int pos) ...{adj[ls ++= pos;}
}
;
int n;
int path[NMAX][NMAX];
LINKT epath[NMAX], nepath[NMAX];
int pre[NMAX];
bool vis[NMAX], del[NMAX];
int min_cost;
int fold[NMAX], fpre[NMAX];

void dfs(int pos) ...{
    
int i;
    vis[pos] 
= true;
    
for(i=0;i<epath[pos].ls;i++...{
        
if(!vis[ epath[pos].adj[i] ]) dfs(epath[pos].adj[i]);
    }

}


bool is_connect(int root) ...{
    
int i;
    memset(vis, 
0sizeof(vis));
    dfs(root);
    
for(i=1;i<=n;i++...{
        
if(!vis[i]) return false;
    }

    
return true;
}

//O(VE)
bool min_tree_graph(int root) ...{
    
int i,j,k;
    
//make sure every node(except root) have in-arc
    if(!is_connect(root)) return false;
    memset(del, 
0sizeof(del));
    min_cost 
= 0;
    
for(i=0;i<=n;i++) fold[i] = fpre[i] = i;
    
while(true...{
        
for(i=1;i<=n;i++...{
            
if(del[i] || i == root) continue;
            pre[i] 
= i;
            path[i][i] 
= INF;//delete self-cycle
            for(j=0;j<nepath[i].ls;j++...{
                
int t = nepath[i].adj[j];
                
if(del[t]) continue;
                
if(path[t][i] < path[ pre[i] ][i]) pre[i] = fpre[fold[i]] = t;
            }

        }
//find min in-arc
        for(i=1;i<=n;i++...{
            
if(del[i] || i == root) continue;
            j 
= i;
            memset(vis, 
0sizeof(vis));
            
while(!vis[j] && j != root) ...{
                vis[j] 
= true;
                j 
= pre[j];
            }

            
if(j == root) continue;//no cycle
            i = j;//cycle begin node
            min_cost += path[ pre[i] ][i];
            
for(j=pre[i]; j != i ;j=pre[j]) ...{
                del[j] 
= true;//fold cycle
                min_cost += path[ pre[j] ][j];//add cycle cost
            }

            
for(j=0;j<nepath[i].ls;j++...{
                
int t = nepath[i].adj[j];
                
if(del[t]) continue;
                path[t][i] 
-= path[ pre[i] ][i];
            }
//i is new fold node
            for(j=pre[i]; j != i ;j=pre[j]) ...{
                
for(k=0;k<epath[j].ls;k++...{
                    
int t = epath[j].adj[k];
                    
if(del[t]) continue;
                    
if(path[i][t] == INF) ...{
                        epath[i].push_back(t);
                        nepath[t].push_back(i);
                    }

                    path[i][t] 
= min(path[i][t], path[j][t]);
                }

                
for(k=0;k<nepath[j].ls;k++...{
                    
int t = nepath[j].adj[k];
                    
if(del[t]) continue;
                    
if(path[t][i] == INF) ...{
                        epath[t].push_back(i);
                        nepath[i].push_back(t);
                    }

                    
if(path[t][i] > path[t][j] - path[ pre[j] ][j]) ...{
                        path[t][i] 
= path[t][j] - path[ pre[j] ][j];
                        fold[i] 
= j;//record fold node
                    }

                }

            }
//make new graph
            break;
        }

        
if(i > n) ...{
            
for(i=1;i<=n;i++...{
                
if(del[i] || i == root) continue;
                min_cost 
+= path[ pre[i] ][i];
            }

            
break;
        }
//graph no cycle
    }
//while have cycle
    return true;
}


int main() ...{
    
int i,j,m,t;
    scanf(
"%d"&t);
    
for(i=1;i<=t;i++...{
        scanf(
"%d %d"&n,&m);
        memset(path, 
0x7f,sizeof(path));
        
for(j=0;j<=n;j++) epath[j].ls = nepath[j].ls = 0;
        
while(m --...{
            
int x,y,z;
            scanf(
"%d %d %d"&x,&y,&z);
            x 
++; y ++;
            
if(x == y) continue;
            
if(path[x][y] == INF) ...{
                epath[x].push_back(y);
                nepath[y].push_back(x);
            }

            path[x][y] 
= min(path[x][y], z);
        }

        
if!min_tree_graph(1) ) printf("Case #%d: Possums! ", i);
        
else printf("Case #%d: %d ", i,min_cost);
    }

}

版权声明:本文为huangwei1024(huangwei.pro)原创文章,转载请注明作者和出处。

最小树与最小树形图

  • 2013年06月11日 10:41
  • 765KB
  • 下载

有向图的最小生成树,最小树形图

转载: 有固定根的最小树形图求法O(VE): 首先消除自环,显然自环不在最小树形图中。然后判定是否存在最小树形图,以根为起点DFS一遍即可。 之后进行以下步骤。 设cost为最...

POJ 3164 最小树形图裸题

题意: 给定n个点 m条有向边(点标从1开始) 下面n个点坐标 下面m条边   问最小树形图权值(无则输出一句话) 思路:最小树形图裸题 #include #include #i...

hdoj 4009 Transfer water 【无源点最小树形图】【好题】

题目:hdoj 4009 Transfer water 题意:题目有点长,说是有个村子,有 n 户人家要用水,他们加的位置用三维坐标来表示(x,y,z),他们有两种选择: 1:自己挖一口井...

最小树形图poj3164

之前学习过这个算法,后来没有复习,昨天上海网络赛的C题就出现了,而在OJ上的例子也不多。当时一味的同Kruska去解,头都大了,完全忘记了有向图应该用最小树形图。昨晚回头来看,还看了一段时间才明白,真...

HDU 4966 GGS-DDU(无固定根最小树形图)

题目链接; HDU 4966 GGS-DDU 题意: 有n门课程需要学习,每门课程的初始等级是0,最高等级是num[i],有m个补习班可以用来提升课程等级, 参加第i个补习班的条件是第a[i]...
  • Ramay7
  • Ramay7
  • 2016年05月21日 00:00
  • 182

poj 3164 最小树形图模板题目,朱刘算法

Command Network Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 11621   Accepted...

HDU 2121 不定根最小树形图

题意:给你一张有向图,问是否能找出一个点,使得他到所有点的距离最小。 思路:还是不定根最小树形图,虚拟一个S作为根,与所有点相连,然后跑一遍朱刘算法。 至于找出这个点,我们将S与所有点都连起来的时...

HDU2121 Ice_cream’s world II【最小树形图】【不定根】

题目大意:一个国家有N个城市,M条有向道路,国王想要选一个城市为首都, 使得这个城市既能连接所有的城市,而且总的路程最短。若能找到这个城市,则 输出最短路程和城市编号。 思路:求有向图的最小树形图,不...

UVa 11865 二分+最小树形图

题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:最小树形图
举报原因:
原因补充:

(最多只允许输入30个字)