HDU 2448 Mining Station on the Sea(floyd+KM)
来源:互联网 发布:papago翻译软件 编辑:程序博客网 时间:2024/05/17 08:24
题目链接:点击打开链接
题目大意:在m个采矿站中有n只船,这n只船要回到n个港口,每个港口只能停留有一只船。给出距离,求这n只船全部回到港口要走的总路程的最小值。
最短路+最小权匹配,两部分都是非常裸的。
先用floyd求出m个采矿站到n个港口的最短路程。题目中有这么一句话:“Notice that once the ship entered the port, it will not come out!”,所以使用floyd的时候要注意港口不能作为中间点。然后再用KM求出二分图的最大权匹配。
#include <set>#include <map>#include <cmath>#include <stack>#include <queue>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;typedef long long LL;#define FIN freopen("in.txt", "r", stdin);#define FOUT freopen("out.txt", "w", stdout);#define lson l, mid, cur << 1#define rson mid + 1, r, cur << 1 | 1const int INF = 0x3f3f3f3f;const int MAXN = 3e2 + 50;int n, m, k, p, loc[MAXN], dis[MAXN][MAXN];int nx, ny, linker[MAXN], lx[MAXN], ly[MAXN], slack[MAXN], G[MAXN][MAXN];bool visx[MAXN], visy[MAXN];bool dfs(int x){ visx[x] = true; for (int y = 1; y <= ny; y++) { if (visy[y]) continue; int tmp = lx[x] + ly[y] - G[x][y]; if (tmp == 0) { visy[y] = true; if (linker[y] == -1 || dfs(linker[y])) { linker[y] = x; return true; } } else slack[y] = min(slack[y], tmp); } return false;}int KM(){ memset(linker, -1, sizeof(linker)); memset(ly, 0, sizeof(ly)); for (int x = 1; x <= nx; x++) { lx[x] = -INF; for (int y = 1; y <= ny; y++) lx[x] = max(lx[x], G[x][y]); } for (int x = 1; x <= nx; x++) { for (int i = 1; i <= ny; i++) slack[i] = INF; while (true) { memset(visx, false, sizeof(visx)); memset(visy, false, sizeof(visy)); if (dfs(x)) break; int d = INF; for (int i = 1; i <= ny; i++) if (!visy[i]) d = min(d, slack[i]); for (int i = 1; i <= nx; i++) if (visx[i]) lx[i] -= d; for (int i = 1; i <= ny; i++) if (visy[i]) ly[i] += d; else slack[i] -= d; } } int res = 0; for (int i = 1; i <= ny; i++) if (linker[i] != -1) res += G[linker[i]][i]; return res;}void floyd(){ for (int k = n + 1; k <= n + m; k++) //港口的编号为1~n,不能作为中间点 for (int i = 1; i <= n + m; i++) for (int j = 1; j <= n + m; j++) if (dis[i][k] != INF && dis[k][j] != INF) dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);}int main(){#ifndef ONLINE_JUDGE FIN;#endif // ONLINE_JUDGE while (~scanf("%d%d%d%d", &n, &m, &k, &p)) { nx = ny = n; for (int i = 1; i <= n + m; i++) for (int j = 1; j <= n + m; j++) { if (i == j) dis[i][j] = 0; else dis[i][j] = INF; G[i][j] = 0; } for (int i = 1; i <= n; i++) { scanf("%d", &loc[i]); loc[i] += n; //港口编号为1~n,采矿站编号为n+1~n+m } for (int i = 0; i < k; i++) { int a, b, c; scanf("%d%d%d", &a, &b, &c); dis[a + n][b + n] = dis[b + n][a + n] = c; } for (int i = 0; i < p; i++) { int d, e, f; scanf("%d%d%d", &d, &e, &f); dis[d][e + n] = dis[e + n][d] = f; } floyd(); for (int i = 1; i <= nx; i++) for (int j = 1; j <= ny; j++) G[i][j] = -dis[j][loc[i]]; printf("%d\n", -KM()); } return 0;}
0 0
- HDU 2448 Mining Station on the Sea(floyd+KM)
- Mining Station on the Sea (hdu 2448 SPFA+KM)
- HDU 2448 Mining Station on the Sea(KM最大匹配+floyd)
- hdu 2448 Mining Station on the Sea【最短路Floyd+KM 最佳匹配】
- hdu 2448 Mining Station on the Sea //floyed+km算法
- HDU 2448 Mining Station on the Sea 最短路+KM
- HDU 2448 Mining Station on the sea(KM算法)
- HDU 2448 Mining Station on the Sea(Floyd+最优匹配)
- HDU 2448 Mining Station on the Sea(Floyd+最优匹配)
- HDU 2448 Mining Station on the Sea(Floyd+最优匹配)
- HDU2448 Mining Station on the Sea Floyd算法+KM算法
- hdu 2448 Mining Station on the Sea(最短路径+KM)
- hdu 2448 Mining Station on the Sea
- HDU 2448 Mining Station on the Sea
- Mining Station on the Sea----dijkstra+KM
- 【KM匹配】 HDOJ 2448 Mining Station on the Sea
- hdu 2448 Mining Station on the Sea(KM匹配//费用流)
- hdu 2448 Mining Station on the Sea km算法+最短路
- 35 第一个只出现一次的字符
- PAT乙级.1012. 数字分类 (20)
- 无向图最小割
- 【Leetcode】 83. Remove Duplicates from Sorted List 【两个指针】
- python的多线程基础设施
- HDU 2448 Mining Station on the Sea(floyd+KM)
- java网络编程
- 206. Reverse Linked List
- git快速入门(一)git环境配置
- Java个人理解之时间的使用
- LeetCode进阶之路(4Sum)
- 野指针与野指针的避免
- 欢迎使用CSDN-markdown编辑器
- Java-static