度限制最小生成树 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 ...
随机推荐
- RabbitMQ入门_11_DLX
参考资料:https://www.rabbitmq.com/dlx.html 队列中的消息可能会成为死信消息(dead lettered).让消息成为死信消息的事件有: 消息被取消确认(nack 或 ...
- C#中的约束类型
- English trip V1 - 2.Don't Do That Teacher:Patrick Key: 祈使句(imperatives)
什么是祈使句? What's imperatives? 求或者希望别人做什么事或者不做什么事时用的句子:带有命令的语气 In this lesson you will learn how to ...
- Nanami's Digital Board CodeForces - 434B (棋盘dp)
大意: 给定01矩阵, m个操作, 操作1翻转一个点, 操作2求边界包含给定点的最大全1子矩阵 暴力枚举矩形高度, 双指针统计答案 #include <iostream> #include ...
- python-day49--前端 html
一.列表标签 1.有序列表 <ol> (order list ) 在浏览器中显示包括:padding , 有序排列 <li>:列表中的每一项. 2.无序列表 ...
- python-day12--函数进阶
1.命名空间: 分三种:全局命名空间,局部命名空间,内置命名空间. 加载顺序:内置命名空间→全局命名空间→局部命名空间 取值顺序:局部命名空间→全局命名空间→内置命名空间 2.作用域: 作用域就是作用 ...
- HDU-4856 Tunnels (BFS+状压DP)
Problem Description Bob is travelling in Xi’an. He finds many secret tunnels beneath the city. In hi ...
- consumer filter
ProtocolFilterWrapper中buildInvokerChain方法把Filter链在一起,调用执行的时候,逐个执行filter,最后执行filter中的invoker. //Proto ...
- spring boot 学习(三)API注解记录及测试
spring boot API注解记录及测试 部分注解解析 @Controller : 修饰创建处理 http 处理对象,一般用于页面渲染时使用. @RestController : Json数据交互 ...
- PHP与MYSQL数据库链接方法
<?php //Mysqli链接数据库的方法 $host='localhost';//主机地址 $dbname='mydata2017';//数据库名 $username='root';//用户 ...