博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1639度限制生成树
阅读量:6691 次
发布时间:2019-06-25

本文共 2299 字,大约阅读时间需要 7 分钟。

题目就是给出一些英文名称, 并且要求源点为park的入度不能超过k

给出思路:
1.首先抹去park, 在剩下的连通分量中求出最小生成树加入答案, 此时的度是最小的, 即如果现在的度大于k, 则无解(题目好像没这个情况)
2.由于我们一开始删去了和park相邻的每一条边, 所以我们要加上每个联通子图到park的最小边, 但这样并不是最好的, 我们要把度加到k, 这样会使答案更优(至于具体的操作, 留一点思考的空间, 也可以看我的代码)

#include #include 
#include
#include
#include
using namespace std;const int N = 150;const int oo = 0x3f3f3f;#define FILL(a, b) memset(a, b, sizeof(a))#define rep(i, s, t) for(int i = s; i <= t; ++i)map
id;int insert(string s) { if(!id.count(s)) id[s] = id.size(); return id[s];}struct Edge { int u, v, w;}p[N];struct Part_Prim { int G[N][N], n, m, limit, fa[N]; int dis[N], vis[N], cnt, used[N][N]; void init() { id.clear(); id["Park"] = 1; cnt = 0; rep(i, 1, N-1) rep(j, 1, N-1) G[i][j] = oo; FILL(vis, 0), FILL(used, 0), FILL(p, 0); } int prim(int s, int ret = 0, int add = oo) { int to_root = 0; ++cnt; rep(i, 0, n) dis[i] = oo; dis[s] = 0; rep(i, 1, n-1) { int k = 0; rep(j, 2, n) if(dis[k] > dis[j] && !vis[j]) k = j; if(!k) break; ret += dis[k]; vis[k] = cnt; if(add > G[k][1]) to_root = k, add = G[k][1]; rep(j, 2, n) if(G[k][j] < dis[j] && !vis[j]) dis[j] = G[k][j], fa[j] = k; if(fa[k]) used[k][fa[k]] = used[fa[k]][k] = 1; } used[1][to_root] = used[to_root][1] = 1; return ret + add; } void dfs(int u, int f) { rep(v, 2, n) if(used[u][v] && v ^ f) { p[v] = p[u]; if(G[u][v] ^ oo && G[u][v] > p[v].w) p[v] = (Edge) {u, v, G[u][v]}; dfs(v, u); } } int parking(int ret = 0, int t = 0) { rep(i, 2, n) if(!vis[i]) ret += prim(i);// cout << ret << endl; while(cnt++ < limit) { dfs(1, 0); rep(i, 2, n) if(G[1][i] ^ oo && !used[1][i] && p[i].w-G[1][i] > p[t].w-G[1][t]) t = i; ret -= p[t].w-G[1][t]; // cout << p[t].w << "!" << endl; used[1][t] = used[t][1] = 1; used[p[t].u][p[t].v] = used[p[t].v][p[t].u] = 0; } return ret; } void solve(int _ = 0) { while(~scanf("%d", &_)) { init(); while(_--) { string s1, s2; int w, u, v; cin >> s1 >> s2 >> w; u = insert(s1), v = insert(s2); G[u][v] = G[v][u] = w; } n = id.size(); scanf("%d", &limit); printf("Total miles driven: %d\n", parking()); } }}WORK;int main() {#ifndef ONLINE_JUDGE freopen("IP.in", "r", stdin); freopen("OP.out", "w", stdout);#endif WORK.solve(); return 0;}

转载于:https://www.cnblogs.com/pbvrvnq/p/8530156.html

你可能感兴趣的文章
WPF-利用Blend写的平面控制闸门开关动画
查看>>
设计模式---外观模式(门面模式)(DesignPattern_Facade)
查看>>
java B2B2C电子商务平台分析之七-Spring Cloud Config
查看>>
Gradle 多渠道打包
查看>>
换芯后的 Edge 浏览器 UI 首曝光,还是熟悉的味道?
查看>>
Spring API 开发简单示例及技巧
查看>>
Confluence 6 修改 Home 目录的位置
查看>>
4Fun获千万元级 Pre-A 轮融资,要做印度的快手
查看>>
你需要知道的conda(原创,转载注明出处)
查看>>
@Controller和@RestController的区别?
查看>>
EasyTabPager
查看>>
Java根据两点经纬度计算距离
查看>>
elastic search head 基本用法
查看>>
Java NIO(三)Channel 通道
查看>>
JavaScript常用数组操作方法,包含ES6方法
查看>>
[原创]一篇无关技术的小日记(仅作暂存)
查看>>
swift4.1 系统学习七
查看>>
scrapy突破反爬的几种方式(一)
查看>>
Elasticsearch同步MySQL
查看>>
编程语言之父谈语言设计,龟叔大赞 TypeScript
查看>>