• <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)  編輯 收藏 引用
            日韩久久久久久中文人妻| 色婷婷噜噜久久国产精品12p| 亚洲AV无一区二区三区久久| 无码专区久久综合久中文字幕 | 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 久久国产精品二国产精品| 四虎影视久久久免费| 久久婷婷五月综合97色一本一本| 91久久精品无码一区二区毛片| 99热精品久久只有精品| 久久人人爽人人爽人人爽| 亚洲国产精久久久久久久| 99久久做夜夜爱天天做精品| 国产69精品久久久久99| 少妇精品久久久一区二区三区| 久久激情亚洲精品无码?V| 久久无码人妻一区二区三区午夜| 亚洲国产一成久久精品国产成人综合 | 狠狠综合久久综合中文88| 人妻少妇久久中文字幕一区二区 | 99久久夜色精品国产网站 | 日产精品久久久久久久性色| 色婷婷久久久SWAG精品| 久久精品国产福利国产秒| 久久久久久久久无码精品亚洲日韩| 伊人色综合久久天天网| 日本精品久久久久影院日本| 国产999精品久久久久久| 四虎国产永久免费久久| 国内精品久久九九国产精品| 久久亚洲精品成人AV| 精品熟女少妇av免费久久| 亚洲αv久久久噜噜噜噜噜| 久久经典免费视频| 久久免费看黄a级毛片| 伊人久久五月天| 精品国产乱码久久久久久呢| 久久精品国产免费观看| 精品国产一区二区三区久久久狼| 97久久超碰国产精品2021| 日本免费一区二区久久人人澡 |