程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> Poj 1639 K度限最小生成樹

Poj 1639 K度限最小生成樹

編輯:關於C語言

題意:給出一個無向圖,求在已知頂點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;
            }
      

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved