2011 ACM/ICPC 北京赛区现场赛解题:Peach Blossom Spring
来源:互联网 发布:go语言编程 mobi 编辑:程序博客网 时间:2024/04/30 02:00
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4085
在做这道题之前,建议先看下POJ3123,相关的信息在这里和这里。
说一下这道题的思路吧。
首先判断无解情况,这个很简单,把两个点集做一次二分图匹配看是否全部连通就OK了。
之后用Minimal Steiner Tree那种DP思想求解出dp[i][j]所有结果,其中i是用二进制状态压缩的点集,j是点,dp[i][j]是j到点集的最短路。
最后,用map初始化两个点集中子集相连的最短路,DP求所有点的最短路。
代码
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <map>#define V 55#define A 11#define inf 0x3f3f3f3fusing namespace std;int n, m, k;int vis[V], id[A], per[6];int d[V][V], ans[1 << A][V];map <int, int> mp;bool mat[A][A];bool visit[A];int match[A];int dig(int x){ int cnt = 0; while (x) { if (x % 2 == 1) cnt++; x >>= 1; } return cnt;}void steiner(int n, int a){ int i, j, k, mx, mk, top = (1 << a); for (k = 0; k < n; ++k) { for (i = 0; i < n; ++i) for (j = 0; j < n; ++j) if (d[i][j] > d[i][k] + d[k][j]) d[i][j] = d[i][k] + d[k][j]; } for (i = 0; i < a; ++i) { for (j = 0; j < n; ++j) ans[1 << i][j] = d[j][id[i]]; } for (i = 1; i < top; ++i) { if (0 == (i & (i - 1))) continue; memset(vis, 0, sizeof(vis)); for (k = 0; k < n; ++k) { ans[i][k] = inf; for (int sub = i; sub; sub = (sub - 1) & i) if (ans[i][k] > ans[sub][k] + ans[i - sub][k]) ans[i][k] = ans[sub][k] + ans[i - sub][k]; } for (j = 0; j < n; ++j) { mx = inf; for (k = 0; k < n; ++k) if (ans[i][k] <= mx && 0 == vis[k]) mx = ans[i][mk = k]; for (k = 0, vis[mk] = 1; k < n; ++k) if (ans[i][mk] > ans[i][k] + d[k][mk]) ans[i][mk] = ans[i][k] + d[k][mk]; } if (dig(i % (1 << (a / 2))) == dig(i >> (a / 2))) { int mina = inf; for (int j = 0; j < n; ++j) mina = min(mina, ans[i][j]); mp[i] = mina; } }}bool find(int x, int n){ for (int i = 0; i < n; ++i) { if (mat[x][i] && !visit[i]) { visit[i] = true; if (match[i] == -1 || find(match[i], n)) { match[i] = x; return true; } } } return false;}int hungary(int n){ memset(match, -1, sizeof(match)); int maxi = 0; for (int i = 0; i < n; ++i) { memset(visit, false, sizeof(visit)); if (find(i, n)) maxi++; } return maxi++;}int main(){ int t; scanf("%d", &t); while (t--) { scanf("%d%d%d", &n, &m, &k); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) d[i][j] = inf; d[i][i] = 0; } for (int i = 0; i < m; ++i) { int u, v, w; scanf("%d%d%d", &u, &v, &w); d[u - 1][v - 1] = min(d[u - 1][v - 1], w); d[v - 1][u - 1] = min(d[v - 1][u - 1], w); } for (int kk = 0; kk < n; ++kk) { for (int i = 0; i < n; ++i) for (int j = 0; j < n; ++j) if (d[i][j] > d[i][kk] + d[kk][j]) d[i][j] = d[i][kk] + d[kk][j]; } memset(mat, false, sizeof(mat)); for (int i = 0; i < k; ++i) for (int j = 0; j < k; ++j) { mat[i][j] = (d[i][n - j - 1] == inf ? false : true); } if (hungary(k) != k) puts("No solution"); else { mp.clear(); for (int i = 0; i < k; ++i) id[i] = i; for (int i = 0; i < k; ++i) id[k + i] = n - i - 1; steiner(n, 2 * k); map<int, int> :: iterator i, j; for (i = mp.begin(); i != mp.end(); i++) { for (j = i, j++; j != mp.end(); ++j) { if ((i -> first & j -> first) == 0) { mp[i -> first | j -> first] = min(mp[i -> first | j -> first], i -> second + j -> second); } } } printf("%d\n", mp[(1 << (2 * k)) - 1]); } } return 0;}
- 2011 ACM/ICPC 北京赛区现场赛解题:Peach Blossom Spring
- 2011 ACM/ICPC 北京赛区现场赛解题:Activation
- 2011 ACM/ICPC 北京赛区现场赛解题:GemAnd Prince
- 2011 ACM/ICPC 北京赛区现场赛解题:Qin Shi Huang's National Road System
- 2011 ACM/ICPC 北京赛区现场赛解题:ALetter to Programmers
- 2014 ACM/ICPC 北京赛区现场赛总结!!
- HDU 5117 Fluorescent(2014 ACM/ICPC 北京赛区现场赛)
- 2014 ACM/ICPC 北京赛区网络赛解题报告汇总
- 2011 ACM/ICPC 福州赛区现场赛8.7
- 2014北京赛区现场赛解题报告
- BUPT 238 2011ACM北京赛区现场赛A题
- HDU-5112-A Curious Matt (2014ACM/ICPC北京赛区现场赛A题!)
- HDU-5122-K.Bro Sorting (2014ACM/ICPC北京赛区现场赛K题!)
- HDU-5112-A Curious Matt (2014ACM/ICPC北京赛区现场赛A题!)
- HDU 5115 Dire Wolf(2014ACM/ICPC北京赛区现场赛D)
- hdu4085 Peach Blossom Spring
- Peach Blossom Spring HDU
- HDU4085-Peach Blossom Spring
- 【雷帝嘎嘎】:宁可打光棍也不和IT投资人约会的10个理由
- 浅谈css中图片定位之所有图标放在一张图上(一)
- 要冷静
- NDK r7 的新特性
- 高精度运算——正实数的加减运算
- 2011 ACM/ICPC 北京赛区现场赛解题:Peach Blossom Spring
- Dropbox:不仅仅是储存和同步
- Belkin推出无线拍照遥控器,专为iPhone而设的偷拍利器
- 转福布斯荐75本经商必读
- xen虚拟windows使用vnc桌面鼠标位置偏移现象的解决
- Linux TCP/IP 协议栈的关键数据结构Socket Buffer(sk_buff )
- 软件性能
- java多线程笔记
- 文件访问(库函数)