度限制最小生成树 POJ 1639 贪心+DFS+prim
很好的解题报告:
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的更多相关文章
- K度限制MST poj 1639
/* k度限制MST:有一个点的度<=k的MST poj 1639 要求1号点的度不超过k 求MST 我们先把1号点扔掉 跑MST 假设有sum个连通分支 然后把这sum个分支连到1上 就得到了 ...
- 【POJ 1639】 Picnic Planning (最小k度限制生成树)
[题意] 有n个巨人要去Park聚会.巨人A和先到巨人B那里去,然后和巨人B一起去Park.B君是个土豪,他家的停车场很大,可以停很多车,但是Park的停车场是比较小.只能停k辆车.现在问你在这个限制 ...
- poj 1639 Picnic Planning 度限制mst
https://vjudge.net/problem/POJ-1639 题意: 有一群人,他们要去某一个地方,每个车可以装无数个人,给出了n条路,包含的信息有路连接的地方,以及路的长度,路是双向的,但 ...
- hiho一下 第二十九周 最小生成树三·堆优化的Prim算法【14年寒假弄了好长时间没搞懂的prim优化:prim算法+堆优化 】
题目1 : 最小生成树三·堆优化的Prim算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 回到两个星期之前,在成功的使用Kruscal算法解决了问题之后,小Ho产生 ...
- 求最小生成树(暴力法,prim,prim的堆优化,kruskal)
求最小生成树(暴力法,prim,prim的堆优化,kruskal) 5 71 2 22 5 21 3 41 4 73 4 12 3 13 5 6 我们采用的是dfs的回溯暴力,所以对于如下图,只能搜索 ...
- 小黑的镇魂曲(HDU2155:贪心+dfs+奇葩解法)
题目:点这里 题目的意思跟所谓的是英雄就下100层一个意思……在T秒内能够下到地面,就可以了(还有一个板与板之间不能超过H高). 接触这题目是在昨晚的训练赛,当时拍拍地打了个贪心+dfs,果断跟我想的 ...
- POJ.3172 Scales (DFS)
POJ.3172 Scales (DFS) 题意分析 一开始没看数据范围,上来直接01背包写的.RE后看数据范围吓死了.然后写了个2^1000的DFS,妥妥的T. 后来想到了预处理前缀和的方法.细节以 ...
- 【bzoj3252】攻略 贪心+DFS序+线段树
题目描述 题目简述:树版[k取方格数] 众所周知,桂木桂马是攻略之神,开启攻略之神模式后,他可以同时攻略k部游戏. 今天他得到了一款新游戏<XX半岛>,这款游戏有n个场景(scene),某 ...
- hdu6060[贪心+dfs] 2017多校3
/* hdu6060[贪心+dfs] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long L ...
随机推荐
- HDU 6114 Chess
Chess 思路:求C(n,m),除法取余用乘法逆元算. 代码: #include<bits/stdc++.h> using namespace std; #define ll long ...
- vysor 破解 (插件 V1.7.8 客户端2.1.0)
0.环境 mac os ===19年更新-客户端破解=== 换了个电脑,老的Chrome 插件各种问题,就换了客户端,然后就是一片模糊... 参考文档:https://www.sdbeta.com/w ...
- smarty课程---smarty3的安装和使用
smarty课程---smarty3的安装和使用 一.总结 一句话总结:smarty 是什么,就不多说了,用过php,接触过php的人都对smarty 再熟悉不过了.它是一个很强大的代码分离软件,作为 ...
- Confluence 6 LDAP 成员结构设置
用户组成员属性(Group Members Attribute) 这个属性字段将在载入用户组成员的时候使用.例如: member 用户成员属性(User Membership Attribute) 这 ...
- java回收算法
两个最基本的java回收算法:复制算法和标记清理算法 复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B.此为新生代最常用的算法 ...
- 将 HttpPostedFile 转换成 Image 或者 Bitmap
代码如下: HttpFileCollection httpfiles = context.Request.Files; files = httpfiles[i]; Image im = Image.F ...
- redis 处理命令的过程
redis版本:redis-3.2.9 在客户端输入 set name zhang,调试redis服务器,得到调用栈如下: 在dictReplace中加了断点,结果跳出来4个线程,redis还是单进程 ...
- python 利用quick sort思路实现median函数
# import numpy as np def median(arr): #return np.median(arr) arr.sort() return arr[len(arr)>>1 ...
- Hibernate优化策略
https://blog.csdn.net/blueheart20/article/details/21019043 https://blog.csdn.net/yerenyuan_pku/artic ...
- Microsoft Office相关开发组件
安装office,直接引用COM控件 C#4提供对PIA引用的一种方式:链接(编译器只会将PIA中需要的部分直接嵌入到程序集中),变体(variant)被视为动态类型,以减少强制转换需要的开销: 不安 ...