• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 33,  comments - 33,  trackbacks - 0
            題意:給出一個無向圖,求在已知頂點v0的度不超過K的情況下,所得的最小生成樹
            題解:
            首先不考慮v0點,先求得v1-v(n-1)的MST,然后分兩種情況考慮:
            令d為v0的度
            情況1 : 當d == 1,時 ,答案顯然是min{edge(0,i)}+MST{v1-v(n-1)}
            當 1 < d <= K時,考慮逐步添加一條{0-i}邊,添加邊后勢必構成回路,然后在回路中找到
            權值最大的邊,然后在MST中將這條邊刪除并修改為{0-i}
            代碼:
            #include <stdio.h>
            #include 
            <algorithm>
            #include 
            <iostream>
            #include 
            <string>
            #include 
            <map>
            using namespace std;

            const int V = 21;
            const int INF = 1 << 30;
            int n;

            struct Edge
            {
                
            int from;
                
            int to;
                
            int weight;
            }
            ;

            map
            <string,int> Map;
            int graph[V][V];
            Edge edges[V];
            int vertexNum;
            int s;
            bool visited[V];//邊(0,i)是否在edges中

            void init()
            {
                memset(visited,
            0,sizeof(visited));
                Map.clear();
                
            for(int i = 0; i < V; ++i)
                
            {
                    
            for(int j = 0; j < V; ++j)
                    
            {
                        graph[i][j] 
            = INF;
                    }

                }

            }



            void input()
            {
                
            string name1,name2;
                
            int dis;
                Map[
            "Park"= 0;
                
            int k = 1;
                
            for(int i = 0; i < n; ++i)
                
            {
                    cin 
            >> name1 >> name2 >> dis;
                    
            if(Map.find(name1) == Map.end())
                        Map[name1] 
            = k++;
                    
            if(Map.find(name2) == Map.end())
                        Map[name2] 
            = k++;
                    
            int id1 = Map[name1];
                    
            int id2 = Map[name2];
                    graph[id1][id2] 
            = graph[id2][id1] = dis;
                }

                scanf(
            "%d",&s);
            }


            //求v0 - v(_vertexNum-1)的最小生成樹
            int Prim(int _vertexNum)
            {
                
            int mstWeight = 0;
                
            for(int i = 1; i < _vertexNum - 1++i)
                
            {
                    edges[i].from 
            = 1;
                    edges[i].to 
            = i + 1;
                    edges[i].weight 
            = graph[1][i+1];
                }

                
            for (int i = 2; i < _vertexNum; ++i)
                
            {
                    
            int id = i-1;
                    
            int minW = edges[i-1].weight;
                    
            for (int j = i; j < _vertexNum-1++j)
                    
            {
                        
            if (minW > edges[j].weight)
                        
            {
                            minW 
            = edges[j].weight;
                            id 
            = j;
                        }

                    }

                    mstWeight 
            += minW;

                    swap(edges[i
            -1],edges[id]); 
                    
            int k = edges[i-1].to;

                    
            for (int j = i; j < _vertexNum -1++j)
                    
            {
                        
            int v = edges[j].to;
                        
            int w = graph[k][v];
                        
            if(w < edges[j].weight)
                        
            {
                            edges[j].weight 
            = w;
                            edges[j].from 
            = k;
                        }

                    }

                }

                
            return mstWeight;
            }


            //返回回路中最大的邊
            bool isCycle;
            void maxWeightInCycle(int _mv,int _from,int _to,int& _maxW,int& _id)
            {
                
            if (_to == _mv)
                
            {
                    isCycle 
            = true;
                    
            return;
                }

                
            for (int i = 0; i < vertexNum-1++i)
                
            {
                    
            if (edges[i].from != _to && edges[i].to != _to)
                    
            {
                        
            continue;
                    }

                    
            if (edges[i].from == _to && edges[i].to != _from)
                    
            {
                        maxWeightInCycle(_mv,_to,edges[i].to,_maxW,_id);
                        
            if (isCycle)
                        
            {
                            
            if (_maxW < edges[i].weight && edges[i].to != 0)
                            
            {
                                _maxW 
            = edges[i].weight;
                                _id 
            = i;
                            }

                            
            break;
                        }

                    }

                    
            else if(edges[i].to == _to && edges[i].from != _from)
                    
            {
                        maxWeightInCycle(_mv,_to,edges[i].from,_maxW,_id);
                        
            if (isCycle)
                        
            {
                            
            if (_maxW < edges[i].weight && edges[i].from != 0)
                            
            {
                                _maxW 
            = edges[i].weight;
                                _id 
            = i;
                            }

                            
            break;
                        }

                    }

                }

            }


            void Test()
            {
                init();
                input();
                vertexNum 
            = Map.size();
                
                
            int ans = Prim(vertexNum);//v0 - vn-1
                int minW = INF; 
                
            int id = -1;
                
            for (int i = 1; i < vertexNum; ++i)
                
            {
                    
            if (minW > graph[0][i])
                    
            {
                        minW 
            = graph[0][i];
                        id 
            = i;
                    }

                }

                ans 
            += graph[0][id];
                visited[id] 
            = true;
                
            //添加邊(0,id)
                edges[0].from = 0;
                edges[
            0].to = id;
                edges[
            0].weight = minW;

                
            //枚舉頂點0 的度
                for (int d = 2; d <= s; ++d)
                
            {
                    
            int dec = INF;
                    
            int edgeId = -1;
                    id 
            = -1;
                    
            for (int i = 1; i < vertexNum; ++i)
                    
            {
                        
            if (visited[i])//已經在MST樹中了
                        {
                            
            continue;
                        }

                        
            int maxW = 0,maxId = -1;
                        isCycle 
            = false;
                        
            //添加邊(0-i),并返回回路最大邊
                        maxWeightInCycle(0,0,i,maxW,maxId);
                        
            if (dec > graph[0][i] - maxW)
                        
            {
                            dec 
            = graph[0][i] - maxW;
                            edgeId 
            = maxId;
                            id 
            = i;
                        }

                    }

                    
            if (dec >= 0)
                    
            {
                        
            break;
                    }

                    
            else
                    
            {
                        
            //將回路最大邊刪除,并修改為0點的邊
                        if (edgeId != -1)
                        
            {
                            edges[edgeId].from 
            = 0;
                            edges[edgeId].to 
            = id;
                            edges[edgeId].weight 
            = graph[0][id];
                        }

                        visited[id] 
            = true;
                        ans 
            += dec;
                    }

                }

                printf(
            "Total miles driven: %d\n",ans);
            }


            int main()
            {
                
            //freopen("data.txt","r",stdin);
                while(scanf("%d",&n) != EOF)
                
            {
                    Test();
                }

                
            return 0;
            }


            posted on 2011-06-02 11:49 bennycen 閱讀(1366) 評論(0)  編輯 收藏 引用
            久久精品国产亚洲AV忘忧草18 | 久久久久久一区国产精品| 免费精品99久久国产综合精品| 久久综合综合久久狠狠狠97色88| 国产精品久久久天天影视香蕉 | 久久综合色区| 久久精品99久久香蕉国产色戒 | 久久亚洲AV无码精品色午夜| jizzjizz国产精品久久| 午夜精品久久久久久| 波多野结衣中文字幕久久| 久久婷婷午色综合夜啪| 色综合合久久天天综合绕视看| 国内精品久久久久久久久电影网| 亚洲国产精品热久久| 亚洲色欲久久久综合网| 色综合久久中文字幕综合网| 久久免费国产精品一区二区| 中文精品久久久久人妻不卡| 久久久久久无码国产精品中文字幕| 久久一日本道色综合久久| 一本色道久久综合| 国产综合免费精品久久久| 国产精品一区二区久久精品| 亚洲综合伊人久久综合| 中文字幕久久精品| 午夜福利91久久福利| 久久免费大片| 青青草原综合久久大伊人导航| 97久久精品人人做人人爽| 色综合久久天天综合| 久久精品国产亚洲网站| 婷婷综合久久狠狠色99h| a高清免费毛片久久| 久久国产精品一区二区| AV狠狠色丁香婷婷综合久久 | 狠狠色伊人久久精品综合网| 国产精品九九久久免费视频 | 久久久久久久综合日本| 日韩va亚洲va欧美va久久| 欧美伊人久久大香线蕉综合69|