POJ 1639 最小度限制生成树

来源:互联网 发布:js 设置session属性值 编辑:程序博客网 时间:2024/05/17 04:39
#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[N][N], dis[N], max_edge[N], pre[N], vis[N], fst[N];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;}

0 0