最小树形图

原创 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
  • 下载

【有向图的最小树形图---朱刘算法】模板

最小树形图 找到一个关于树的学习网址,赞~  http://acm.nudt.edu.cn/~twcourse/Tree.html 无向图的最小生成树可以用prim算法或者Krusual算...

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

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

【最小树形图】

给定一个有向带权图G与其中的一个节点u,找出一个以u为根节点,权和最小的有向生成树,有向生成树即为树形图。 求固定根的最小树形图,由于边都是有向边所以不可以用kruskal,prim,而应该用传说中...

HDU 2121 Ice_cream’s world II (不定根最小树形图求根)

题意: N<=1000,M<=10000,不定根最小树形图,输出最小权和相应的根位置N<=1000, M<=10000, 不定根最小树形图, 输出最小权和相应的根位置 分析: 设一个虚根,然后...
  • lwt36
  • lwt36
  • 2015-11-03 23:21
  • 211

【TOJ】2248 Channel Design 最小树形图——朱刘算法

传送门:【TOJ】2248 Channel Design 题目大意:

HDU 4009 最小树形图

/******************************************************************************** 模板题。。。问题是比赛的时候...

最小树形图-朱刘算法

最小树形图--朱刘算法

hdu 4009 Transfer water 最小树形图

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4009 题目大意: 在山上有N户人家,每家的坐标为(xi, yi, zi)。每户人家要吃水,要么自己...

【UVa】11183 Teen Girl Squad 最小树形图

题目分析:最小树形图模板题。。。。。 码完以后t
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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