CodeForces - 240E Road Repairs(最小树形图+输出路径)
2015-09-11 22:06
573 查看
题目大意:有N个城市,城市1是首都
有M条路,路的状态有两种,一种是可行的,另一种是不可行的,不可行的可以修成可行,但要花1单位的费用
现在问,要让首都能到任意城市,需要花费的最小代价是多少,需要修的路是哪几条
解题思路:就是最小树形图+输出路径了
有M条路,路的状态有两种,一种是可行的,另一种是不可行的,不可行的可以修成可行,但要花1单位的费用
现在问,要让首都能到任意城市,需要花费的最小代价是多少,需要修的路是哪几条
解题思路:就是最小树形图+输出路径了
[code]#include <cstdio> #include <cstring> using namespace std; const int N = 2000010; const int INF = 0x3f3f3f3f; struct Edge{ int u, v, d, dd, id; Edge() {} Edge(int u, int v, int d, int id): u(u), v(v), d(d), id(id), dd(d){}; }; const int M = 2000010; struct Used{ int pre, id; }U[M]; int UseEdge[M]; struct DirectorMT{ int n, m, tot; Edge edges ; int vis , id , in , pre ; int preEdge ; void init(int n) { this->n = n; m = 0; } void AddEdge(int u, int v, int mark, int id) { edges[m++] = Edge(u, v, mark, id); } int DirMt(int root) { tot = m; int ans = 0; while (1) { for (int i = 0; i < n; i++) in[i] = INF; for (int i = 0; i < m; i++) { int u = edges[i].u; int v = edges[i].v; if (edges[i].d < in[v] && u != v ) { in[v] = edges[i].d; pre[v] = u; preEdge[v] = edges[i].id; } } for (int i = 0; i < n; i++) { if (i == root) continue; if (in[i] == INF) return -1; } memset(id, -1, sizeof(id)); memset(vis, -1, sizeof(vis)); in[root] = 0; int cnt = 0; for (int i = 0; i < n; i++) { ans += in[i]; int v = i; //该边被使用了 if (i != root) UseEdge[preEdge[i]]++; while (vis[v] != i && v != root && id[v] == -1) { vis[v] = i; v = pre[v]; } if (v != root && id[v] == -1) { for (int u = pre[v]; u != v; u = pre[u]) id[u] = cnt; id[v] = cnt++; } } if (cnt == 0) break; for (int i = 0; i < n; i++) if (id[i] == -1) id[i] = cnt++; for (int i = 0; i < m; i++) { int v = edges[i].v; edges[i].v = id[edges[i].v]; edges[i].u = id[edges[i].u]; //因为有新的边进来了,如果用到该边的话,那么上一条边就要被取消掉了 if (edges[i].u != edges[i].v) { edges[i].d -= in[v]; U[tot].id = edges[i].id; U[tot].pre = preEdge[v]; edges[i].id = tot; tot++; } } n = cnt; root = id[root]; } for (int i = tot - 1; i >= m; i--) if (UseEdge[i]) { UseEdge[U[i].id]++; UseEdge[U[i].pre]--; } return ans; } }MT; int n, m; void init() { MT.init(n); int u, v, mark; for (int i = 0; i < m; i++) { scanf("%d%d%d", &u, &v, &mark); u--; v--; MT.AddEdge(u, v, mark, i); } int ans = MT.DirMt(0); if (ans == -1 || ans == 0) { printf("%d\n", ans); return ; } printf("%d\n", ans); for (int i = 0; i < m; i++) if (UseEdge[i] && MT.edges[i].dd) printf("%d\n", i + 1); } int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); scanf("%d%d", &n, &m); init(); return 0; }
相关文章推荐
- hdoj 1022 Train Problem I【栈】
- 使用dup和dup2重定向和还原 http://blog.csdn.net/kangear/article/details/24098315
- hdu5029Relief grain 线段树
- kvm随笔系列二: Qemu中的AIO小结
- 使用Windows的分析等待链(analyze wait chain)来诊断没用响应的应用
- Chain of Responsibility - 责任链模式
- Websphere8 AIX静默安装卸载升级
- ADB server didn't ACK failed to start daemon *解决方案
- AIX采用LV创ASM磁盘组
- 使用Keychain存储用户敏感信息
- linux下tty,控制台,虚拟终端,串口,console(控制台终端)详解http://blog.csdn.net/liaoxinmeng/article/details/5004743
- extmail安装配置
- 10个关于人工智能和机器学习的有趣开源项目
- IO系统性能之二:缓存和RAID如何提高IO
- aix系统查看WWNN命令
- lodash 中文学习拾零之 Chain篇
- sendEmail
- Linux tail 命令详解 http://www.2cto.com/os/201111/110143.html
- 出错file is universal (3 slices) but does not contain a(n) armv7s slice
- 手机 同步失败,失败原因:failed to copy