#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;
}
POJ 1639 最小度限制生成树
最新推荐文章于 2021-05-11 17:15:21 发布