很好的解题报告:

http://blog.csdn.net/new_c_yuer/article/details/6365689

注意两点:

1.预处理环中权值最大的边····

2.可以把去掉度限制后的点看成是连通的,权值为无穷远的点也看做是连通的,反正后面肯定会替换出来的····

我的代码没有预处理出权值最大的边,但是第2点事做到了的,这样便于代码的实现·····

贴代码:

 #include <cstdio>
#include <iostream>
#include <map>
#include <string>
#include <algorithm>
#define INF 0x3f3f3f3f
#define N 505
using namespace std;
map<string,int> ma;
map<string,int>::iterator it;
int n,k;//点的个数,度数限制
bool flag;
long long int ans;//最后的结果
bool in[N][N],vis[N];//加入最小生成树中的边
int edge[N][N],pre[N], next[N],lowcost[N];//边,确定哪些边被加入了最小生成树中,存环中的边,求最小生成树
int Find(char c[])
{
it = ma.find(c);
if(it != ma.end())
return it->second;
ma[c] = ++n;
return n;
}
//用prim函数求一次去掉度限制的点后的最小生成树
void prim()
{
lowcost[] = -;
for(int i=; i<=n; ++i)
{
lowcost[i] = edge[][i];
pre[i] = ;
}
for(int i=; i<=n; ++i)
{
int v;
int minum=INF;
for(int j=; j<=n; ++j)
{
if(lowcost[j] != - && minum >= lowcost[j])
{
minum = lowcost[j];
v = j;
}
}
lowcost[v] = -;
ans += edge[v][pre[v]];
in[v][pre[v]] = in[pre[v]][v] = ;
for(int j=; j<=n; ++j)
{
if(lowcost[j] != - && lowcost[j] > edge[j][v] )
{
lowcost[j] = edge[j][v];
pre[j] = v;
}
}
}
}
//dfs找出环
void dfs(int x)
{
if(x == )
{
flag = true;
return;
}
vis[x] = ;
for(int i = n; i >= ; --i)
{
if(in[x][i] && !vis[i] && !flag)
{
next[x] = i;
dfs(i);
}
}
}
//找环上权值最大的边
void findMax(int x,int &s,int &e,int &maxnum)
{
memset(vis,,sizeof(vis));
flag = false;
dfs(x);
maxnum = edge[][x];
int ne = x;
while(next[ne] != )
{
if(edge[ne][next[ne]] > maxnum)
{
maxnum = edge[ne][next[ne]];
s = ne;
e = next[ne];
}
ne = next[ne];
}
}
//找度限制为k的最小生成树
void kTree()
{
int minum = INF;
int v;
for(int i=; i<=n; ++i)
{
if(edge[][i] < minum)
{
minum = edge[][i];
v = i;
}
}
in[v][] = in[][v] = ;
ans += edge[][v];
for(int t=; t<k; ++t)
{
minum = INF;
v = -;
int s,e,m;
for(int i=; i<=n; ++i)
{
if(!in[][i] && edge[][i] < INF)
{
int ss,ee,maxnum;
findMax(i,ss,ee,maxnum);
if(edge[][i] - maxnum < minum)
{
minum = edge[][i] - maxnum ;
s = ss;
e = ee;
m = minum;
v= i;
}
}
}
if(v == -) break;
if(minum >= ) break;
in[][v] = ;
in[v][] = ;
in[s][e] = ;
in[e][s] =;
ans += minum;
}
printf("Total miles driven: %d\n",ans);
}
// 初始化输入
void initScan()
{
int m;
ma["Park"] = n;
scanf("%d",&m);
memset(edge,0x3f,sizeof(edge));
for(int i=; i<m; ++i)
{
char a1[N],a2[N];
int u,v,w;
scanf("%s %s %d",a1,a2,&w);
u = Find(a1);
v = Find(a2);
edge[u][v] = w;
edge[v][u] = edge[u][v];
}
scanf("%d",&k);
}
int main()
{
initScan();
prim();
kTree();
return ;
}

度限制最小生成树 POJ 1639 贪心+DFS+prim的更多相关文章

  1. K度限制MST poj 1639

    /* k度限制MST:有一个点的度<=k的MST poj 1639 要求1号点的度不超过k 求MST 我们先把1号点扔掉 跑MST 假设有sum个连通分支 然后把这sum个分支连到1上 就得到了 ...

  2. 【POJ 1639】 Picnic Planning (最小k度限制生成树)

    [题意] 有n个巨人要去Park聚会.巨人A和先到巨人B那里去,然后和巨人B一起去Park.B君是个土豪,他家的停车场很大,可以停很多车,但是Park的停车场是比较小.只能停k辆车.现在问你在这个限制 ...

  3. poj 1639 Picnic Planning 度限制mst

    https://vjudge.net/problem/POJ-1639 题意: 有一群人,他们要去某一个地方,每个车可以装无数个人,给出了n条路,包含的信息有路连接的地方,以及路的长度,路是双向的,但 ...

  4. hiho一下 第二十九周 最小生成树三·堆优化的Prim算法【14年寒假弄了好长时间没搞懂的prim优化:prim算法+堆优化 】

    题目1 : 最小生成树三·堆优化的Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 回到两个星期之前,在成功的使用Kruscal算法解决了问题之后,小Ho产生 ...

  5. 求最小生成树(暴力法,prim,prim的堆优化,kruskal)

    求最小生成树(暴力法,prim,prim的堆优化,kruskal) 5 71 2 22 5 21 3 41 4 73 4 12 3 13 5 6 我们采用的是dfs的回溯暴力,所以对于如下图,只能搜索 ...

  6. 小黑的镇魂曲(HDU2155:贪心+dfs+奇葩解法)

    题目:点这里 题目的意思跟所谓的是英雄就下100层一个意思……在T秒内能够下到地面,就可以了(还有一个板与板之间不能超过H高). 接触这题目是在昨晚的训练赛,当时拍拍地打了个贪心+dfs,果断跟我想的 ...

  7. POJ.3172 Scales (DFS)

    POJ.3172 Scales (DFS) 题意分析 一开始没看数据范围,上来直接01背包写的.RE后看数据范围吓死了.然后写了个2^1000的DFS,妥妥的T. 后来想到了预处理前缀和的方法.细节以 ...

  8. 【bzoj3252】攻略 贪心+DFS序+线段树

    题目描述 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏. 今天他得到了一款新游戏<XX半岛>,这款游戏有n个场景(scene),某 ...

  9. hdu6060[贪心+dfs] 2017多校3

    /* hdu6060[贪心+dfs] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long L ...

随机推荐

  1. Codeforces 838A - Binary Blocks(二维前缀和+容斥)

    838A - Binary Blocks 思路:求一下前缀和,然后就能很快算出每一小正方块中1的个数了,0的个数等于k*k减去1的个数,两个的最小值就是要加进答案的值. 代码: #include< ...

  2. m_Orchestrate learning system---三十五、php数据和js数据的解耦:php数据(php代码)不要放到js代码中

    m_Orchestrate learning system---三十五.php数据和js数据的解耦:php数据(php代码)不要放到js代码中 一.总结 一句话总结:也就是以html为中介,用html ...

  3. php7 编译 win32ps 模块

    碰到了很多问题 ,但最终都解决了,感觉不错. 1)下载 php source, php sdk, 以及 win32ps的源代码 2) 参照下面的连接进行编译. https://wiki.php.net ...

  4. android--------热修复介绍

    热修复技术在近年来飞速发展,尤其是在InstantRun方案推出之后,各种热修复技术竞相涌现.国内大部分成熟的主流APP都拥有自己的热修复技术,像手淘.支付宝.QQ.饿了么.美团等等. 代码热修复是最 ...

  5. Sasha and a Very Easy Test CodeForces - 1109E (数学,线段树)

    大意: 给定n元素序列, q个操作: (1)区间乘 (2)单点除(保证整除) (3)区间求和对m取模 要求回答所有操作(3)的结果 主要是除法难办, 假设单点除$x$, $x$中与$m$互素的素因子可 ...

  6. DZY Loves Colors CodeForces - 444C (线段树势能分析)

    大意:有$n$个格子, 初始$i$位置的颜色为$i$, 美丽值为0, 有两种操作 将区间$[l,r]$内的元素全部改为$x$, 每个元素的美丽值增加$|x-y|$, $y$为未改动时的值 询问区间$[ ...

  7. 『PyTorch』第五弹_深入理解autograd_下:函数扩展&高阶导数

    一.封装新的PyTorch函数 继承Function类 forward:输入Variable->中间计算Tensor->输出Variable backward:均使用Variable 线性 ...

  8. OC Xcode中常见的错误

    在开发的过程中难免会遇到很多的错误,可是当看到系统给出的英文时,又不知道是什么意思.所以这篇文章总结了Xcode中常见的一些英文单词及词组,可以帮助初学的人快速了解给出的提示.多练习,就肯定能基本掌握 ...

  9. memory prefix vice ,with out 1

    1● vice 副的   2● with 向后,相反  

  10. poj3020 二分图匹配 最大独立集

    这是一道水题, 这里是最大流解法,之后再补 坑在又忘了反向建边了 题意:给你二维bool数组,让你求出能用多米诺骨牌覆盖所有 1 且骨牌最少的放法(因为多米诺骨牌1*2的结构方便描述,原题没有),原本 ...