POJ 1639 最小度限制生成树
2015-08-10 14:33
190 查看
#include<stdio.h> #include<queue> #include<map> #include<string.h> #include<string> #define max(f, s) (f) > (s)? (f):(s) using namespace std; const int N = 32; const int INF = 0x3f3f3f3f; map<string, int> mS2I; int num, k; int g , dis , max_edge , pre , vis , fst ; struct Node { int v, cap; Node(){}; Node(int iv, int ic):v(iv), cap(ic) {}; bool operator < (const Node& other)const { return cap > other.cap; } }; int prim(int s, int id) { priority_queue<Node> pque; while(!pque.empty()) pque.pop(); pque.push(Node(s, 0)); dis[s] = 0; int ret = 0; while(!pque.empty()) { Node top = pque.top(); pque.pop();// int v = top.v; if(!vis[v]) { vis[v] = id; ret += dis[v]; for(int i = 1; i < num; i++) { if(!vis[i] && g[v][i] != 0 && g[v][i] < dis[i]) { dis[i] = g[v][i]; pre[i] = v; pque.push(Node(i, dis[i])); } } } } return ret; } void update(int cur, int last, int maxedge) { max_edge[cur] = max(maxedge, g[cur][last]); for(int i = 1; i < num; i++) { if(i != last && g[cur][i] != 0 && (pre[cur] == i || pre[i] == cur)) update(i, cur, max_edge[cur]); } } int compute(int para) { return max_edge[para]-g[0][para]; } int solve() { for(int i = 0; i < num; i++) { dis[i] = INF; vis[i] = pre[i] = fst[i] = 0; } int ret = 0; int cnt = 1; for(int i = 1; i < num; i++) { if(!vis[i]){ ret += prim(i, cnt++); } } for(int i = 1; i < num; i++) { int id = vis[i]; if(g[0][i] && (!fst[id] || g[0][i] < g[0][fst[id]]))//? fst[id] = i; } for(int i = 1; i < cnt; i++) { ret += g[0][fst[i]]; g[0][fst[i]] = g[fst[i]][0] = 0; update(fst[i], 0, 0); } k = k - cnt + 1; while(k --) { int tmp = 0; for(int i = 1; i < num; i++) { if(g[0][i] != 0 && (tmp == 0 || max_edge[tmp]-g[0][tmp]<max_edge[i]-g[0][i])) { tmp = i; } } if(max_edge[tmp] <= g[0][tmp]) break; ret = ret-max_edge[tmp]+g[0][tmp]; g[0][tmp] = g[tmp][0] = 0; int p = 0;// for(int i = tmp; pre[i] != 0; i = pre[i]) { if(p == 0 || g[i][pre[i]] > g[p][pre[p]]) p = i; } pre[p] = 0; update(tmp, 0, 0); } return ret; } int main() { int n; char s1[16], s2[16]; while(~scanf("%d", &n)) { int d; mS2I["Park"] = 0; num = 1; memset(g, 0, sizeof(g)); for(int i = 0; i < n; i++) { scanf("%s%s%d", s1, s2, &d); if(!mS2I.count(s1)) mS2I[s1] = num++; if(!mS2I.count(s2)) mS2I[s2] = num++; int u = mS2I[s1], v = mS2I[s2]; if(!g[u][v] || g[u][v] > d){ g[u][v] = g[v][u]= d; } } scanf("%d", &k); printf("Total miles driven: %d\n", solve()); } return 0; }
相关文章推荐
- Lua笔记10-非全局函数
- POJ 3259Wormholes
- 正则表达式验证数字的两种方法
- 隔行变色
- Commons lang3 包ArrayUtils类使用
- CompareNoCase与Compare
- Ubuntu 14.04 FTP服务器--vsftpd的安装和配置
- u3d网络链接状态
- 网页遮层
- UVALive 4730 Kingdom(线段树区间修改+并查集)
- 前端学习
- 不用也要知道的几种算法(PHP版本)
- (转)android自定义控件
- 学渣如何打败学霸
- oracle查看awr、addm报告
- Java面向对象的三种特性
- fcntl的close-on-exec标志
- sitemesh
- Oracle_导入大批量数据到表中的方法
- 最小二乘回归