很好的解题报告:

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 837D - Round Subset(dp)

    837D - Round Subset 思路:dp.0是由2*5产生的. ①dp[i][j]表示选i个数,因子2的个数为j时因子5的个数. 状态转移方程:dp[i][j]=max(dp[i][j],d ...

  2. PHP算法之排序算法(PHP内置排序函数)

    首先用实例来讲述一下PHP内置的一些排序函数 [a / k] sort [/ rsort]:[保留索引关系 / 按键名(保留键名关系,适用于关联数组)] 对数组进行排序,结束时数组单元将被从最低到最高 ...

  3. mybatis: 多对多查询[转]

    加入3个包 log4j-1.2.17.jar mybatis-3.3.0.jar mysql-connector-java-5.1.8.jar log4j需要配置 log4j.properties # ...

  4. php时区设置 warning: strtotime(): It is not safe to rely on the system's timezone settings

    warning: strtotime(): It is not safe to rely on the system's timezone settings warning: strtotime(): ...

  5. 2017-03-03 Oracle在.Net中出现未在本地计算机上注册“OraOLEDB.Oracle”提供程序的错误

    在前面的Oracle配置完成后,打开项目运行出错,出现未在本地计算机上注册“OraOLEDB.Oracle”提供程序的错误,看到“注册”两个字,首先想到,难道还要用命令行注册一下?果不其然,需要手动注 ...

  6. LeetCode--122--卖卖股票的最佳时机II

    问题描述: 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易( ...

  7. 『Python』pycharm常用设置

    学习一下pycharm的快捷操作,提升速度,也提升舒适度,笑. 常用快捷键 ctrl + d :复制粘贴本行到下一行 ctrl + y :删除本行 ctrl + 鼠标点击 :跳转 ctrl + / : ...

  8. IntelliJ Idea工具使用

    以前一直用eclipse/myeclipse开发,最近因为需要学习了intelliJ Idea工具,感觉真的挺好用的..好用的东西就要掌握加以利用,特写一篇简单的总结(只写大体). 一,什么是Inte ...

  9. POJ-3259 Wormholes(判断负环、模板)

    Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...

  10. ORACLE中使用DBMS_SQL获取动态SQL执行结果中的列名和值

    1.获取动态SQL中的列名及类型 DECLARE l_curid INTEGER; l_cnt NUMBER; l_desctab dbms_sql.desc_tab; l_sqltext ); BE ...