HYSBZ - 1001 狼抓兔子(对偶图+最短路)
2015-09-07 22:53
357 查看
题目大意:给出一张图,这张图的每条边都有相应的容量,现在问,从(1,1)到(N,M)的最小割是多少
解题思路:转成对偶图去解决
解题思路:转成对偶图去解决
[code]#include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; const int MAXNODE = 1000010; const int MAXEDGE = MAXNODE * 6; const int INF = 0x3f3f3f3f; struct Edge{ int v, val, next; Edge() {} Edge(int v, int val, int next): v(v), val(val), next(next) {} }E[MAXEDGE]; struct Node { int v, val; Node() {} Node(int v, int val): v(v), val(val) {} bool operator <(const Node &a) const { return val > a.val; } }; int n, m, tot, source, sink; int head[MAXNODE * 2], d[MAXNODE * 2]; bool vis[MAXNODE * 2]; void AddEdge(int u, int v, int cap) { E[tot] = Edge(v, cap, head[u]); head[u] = tot++; u = u ^ v; v = u ^ v; u = u ^ v; E[tot] = Edge(v, cap, head[u]); head[u] = tot++; } void Dijkstra() { for (int i = 1; i <= sink; i++) { d[i] = INF; vis[i] = false; } d[source] = 0; priority_queue<Node> Q; Q.push(Node(source, 0)); while (!Q.empty()) { int u = Q.top().v; Q.pop(); if (vis[u]) continue; vis[u] = true; for (int i = head[u]; ~i; i = E[i].next) { int v = E[i].v; if (d[v] > d[u] + E[i].val) { d[v] = d[u] + E[i].val; Q.push(Node(v, d[v])); } } } printf("%d\n", d[sink]); } void solve() { source = (n - 1) * (m - 1) * 2 + 1, sink = source + 1; memset(head, -1, sizeof(head)); tot = 0; int Min = INF; int val, u, v; for (int i = 1; i <= n; i++) { for (int j = 1; j <= m - 1; j++) { scanf("%d", &val); Min = min(Min, val); if (i == 1) AddEdge(j * 2, sink, val); else if (i != n) { u = 1 + (i - 2) * 2 * (m - 1) + (j - 1) * 2; v = u + 2 * (m - 1) + 1; AddEdge(u, v, val); } else AddEdge(source, 1 + (n - 2) * (m - 1) * 2 + (j - 1) * 2, val); } } for (int i = 1; i <= n - 1; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &val); Min = min(Min, val); if (j == 1) AddEdge(source, 1 + (i - 1) * (m - 1) * 2, val); else if (j != m) { u = 2 + (i - 1) * (m - 1) * 2 + (j - 2) * 2; v = u + 1; AddEdge(u, v, val); } else AddEdge(i * (m - 1) * 2, sink, val); } } for (int i = 1; i <= n - 1; i++) for (int j = 1; j <= m - 1; j++) { scanf("%d", &val); Min = min(Min, val); u = 1 + (i - 1) * (m - 1) * 2 + (j - 1) * 2; v = u + 1; AddEdge(u, v, val); } if (n <= 1 && m <= 1) printf("0\n"); else if (n == 1 || m == 1) printf("%d\n", Min); else Dijkstra(); } int main() { while (~scanf("%d%d", &n, &m)) solve(); return 0; }
相关文章推荐
- Android 数据存储:五大存储之SQLite数据存储
- php curl , fsockopen 函数
- FragmentActivity和Activity的具体区别在哪里
- (转)同一进程中的线程究竟共享哪些资源
- 文章标题
- 迟到问题,其实不扣钱的话就不是问题……
- uva 11324 - The Largest Clique(强联通图+拓扑)
- OWL学习笔记
- 使用libnodave采集西门子840D数控系统S7-300 PLC数据
- linux--Xshell的使用
- 电源管理项目学习笔记
- 一个可大规模悄无声息窃取淘宝/支付宝账号与密码的漏洞 -(埋雷式攻击附带视频演示)
- POJ1007 解题报告
- 微信公共平台开发2 .net
- EnCase v.s. FTK - find out Chinese characters writing in different direction
- HDU 4622 Reincarnation
- BT的文件系统btrfs
- linux--SSH Secure Shell Client
- HDU2.2.7 Train Problem II
- 数学概率问题