• <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 閱讀(1361) 評論(0)  編輯 收藏 引用
            jizzjizz国产精品久久| 久久强奷乱码老熟女网站| 国产精品久久久久aaaa| 久久久久亚洲精品天堂久久久久久| 99久久www免费人成精品| 久久免费视频一区| 一本色道久久88—综合亚洲精品 | 国产aⅴ激情无码久久| 久久久久久午夜成人影院| 久久婷婷五月综合成人D啪| 国产精品VIDEOSSEX久久发布| 久久精品国产亚洲av影院| 久久国产精品免费一区二区三区 | 久久精品国产亚洲AV久| 99久久精品国产高清一区二区| 精品久久久久中文字幕一区| 国产亚洲婷婷香蕉久久精品| 新狼窝色AV性久久久久久| 久久亚洲sm情趣捆绑调教| 久久最新精品国产| 99久久精品国产一区二区蜜芽| 久久久久亚洲av成人网人人软件 | 国产偷久久久精品专区| 久久久久亚洲AV无码去区首| 久久天天躁狠狠躁夜夜96流白浆| 伊人久久大香线焦AV综合影院| 久久人人爽人人爽AV片| 久久艹国产| 久久久久亚洲精品天堂| 久久精品中文无码资源站 | 99久久精品无码一区二区毛片 | 老色鬼久久亚洲AV综合| 亚洲七七久久精品中文国产 | 久久青草国产手机看片福利盒子 | 国产精品亚洲综合久久| 一本色综合久久| 国产精品成人久久久| 香蕉久久av一区二区三区| 国内精品久久久久伊人av| 久久强奷乱码老熟女网站| 少妇内射兰兰久久|