您的位置:首页 > 其它

POJ 1639 最小度限制生成树

2015-08-10 14:33 190 查看
#include<stdio.h>
#include<queue>
#include<map>
#include<string.h>
#include<string>
#define max(f, s) (f) > (s)? (f):(s)

using namespace std;

const int N = 32;
const int INF = 0x3f3f3f3f;

map<string, int> mS2I;

int num, k;
int g

, dis
, max_edge
, pre
, vis
, fst
;

struct Node
{
    int v, cap;
    Node(){};
    Node(int iv, int ic):v(iv), cap(ic) {};
    bool operator < (const Node& other)const
    {
        return cap > other.cap;
    }
};

int prim(int s, int id)
{

    priority_queue<Node> pque;
    while(!pque.empty()) pque.pop();
    pque.push(Node(s, 0));
    dis[s] = 0;
    int ret = 0;
    while(!pque.empty())
    {
        Node top = pque.top();
        pque.pop();//
        int v = top.v;
        if(!vis[v])
        {
            vis[v] = id;
            ret += dis[v];
            for(int i = 1; i < num; i++)
            {
                if(!vis[i] && g[v][i] != 0 && g[v][i] < dis[i])
                {
                    dis[i] = g[v][i];
                    pre[i] = v;
                    pque.push(Node(i, dis[i]));
                }
            }
        }
    }
    return ret;
}

void update(int cur, int last, int maxedge)
{
    max_edge[cur] = max(maxedge, g[cur][last]);
    for(int i = 1; i < num; i++)
    {
        if(i != last && g[cur][i] != 0 && (pre[cur] == i || pre[i] == cur))
            update(i, cur, max_edge[cur]);
    }
}

int compute(int para)
{
    return max_edge[para]-g[0][para];
}

int solve()
{
    for(int i = 0; i < num; i++)
    {
        dis[i] = INF;
        vis[i] = pre[i] = fst[i] = 0;
    }
    int ret = 0;
    int cnt = 1;
    for(int i = 1; i < num; i++)
    {
        if(!vis[i]){
            ret += prim(i, cnt++);
        }
    }
    for(int i = 1; i < num; i++)
    {
        int id = vis[i];
        if(g[0][i] && (!fst[id] || g[0][i] < g[0][fst[id]]))//?
            fst[id] = i;
    }
    for(int i = 1; i < cnt; i++)
    {
        ret += g[0][fst[i]];
        g[0][fst[i]] = g[fst[i]][0] = 0;
        update(fst[i], 0, 0);
    }
    k = k - cnt + 1;
    while(k --)
    {
        int tmp = 0;
        for(int i = 1; i < num; i++)
        {
            if(g[0][i] != 0 && (tmp == 0 || max_edge[tmp]-g[0][tmp]<max_edge[i]-g[0][i]))
            {
                tmp = i;
            }
        }
        if(max_edge[tmp] <= g[0][tmp]) break;

        ret = ret-max_edge[tmp]+g[0][tmp];
        g[0][tmp] = g[tmp][0] = 0;
        int p = 0;//
        for(int i = tmp; pre[i] != 0; i = pre[i])
        {
            if(p == 0 || g[i][pre[i]] > g[p][pre[p]])
                p = i;
        }
        pre[p] = 0;
        update(tmp, 0, 0);
    }
    return ret;
}

int main()
{
    int n;
    char s1[16], s2[16];
    while(~scanf("%d", &n))
    {
        int d;
        mS2I["Park"] = 0;
        num = 1;
        memset(g, 0, sizeof(g));
        for(int i = 0; i < n; i++)
        {
            scanf("%s%s%d", s1, s2, &d);
            if(!mS2I.count(s1))
                mS2I[s1] = num++;
            if(!mS2I.count(s2))
                mS2I[s2] = num++;
            int u = mS2I[s1], v = mS2I[s2];
            if(!g[u][v] || g[u][v] > d){
                g[u][v] = g[v][u]= d;
            }
        }
        scanf("%d", &k);
        printf("Total miles driven: %d\n", solve());
    }

    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: