HDU 3861The King’s Problem 强连通分量分解 + 二分图最小路径覆盖
来源:互联网 发布:坚持 知乎 编辑:程序博客网 时间:2024/05/22 02:20
题目:http://acm.hdu.edu.cn/showproblem.php?pid=3861
题意:一个有向图,让你按规则划分区域,要求划分的区域数最少。1、有边u到v以及有边v到u,则u,v必须划分到同一个区域内。2、一个区域内的两点至少要有一方能到达另一方。3、一个点只能划分到一个区域内。
思路:肯定先强连通分量分解缩点,然后去求二分图的最小路径覆盖,最小路径覆盖:在图中找一些路径(路径数最少),使之覆盖了图中所有的顶点,且每个顶点有且仅和一条路径。最小路径覆盖 = 顶点数 - 最大匹配数
总结:用邻接矩阵记录缩点后的图去二分匹配,超时了,,,于是改成了vector实现的邻接表,就过了,,,
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <vector>using namespace std;const int N = 5010;vector<int> g[N];struct edge{ int to, next;}G[N*20];int dfn[N], low[N], scc[N], st[N];int head[N], match[N];bool vis[N], used[N];int index, top, num, cnt;int n, m;void init(){ memset(head, -1, sizeof head); memset(dfn, -1, sizeof dfn); memset(vis, 0, sizeof vis); index = cnt = top = num = 0;}void add_edge(int v, int u){ G[cnt].to = u; G[cnt].next = head[v]; head[v] = cnt++;}void tarjan(int v){ dfn[v] = low[v] = index++; st[top++] = v; vis[v] = true; int u; for(int i = head[v]; i != -1; i = G[i].next) { u = G[i].to; if(dfn[u] == -1) { tarjan(u); low[v] = min(low[v], low[u]); } else if(vis[u]) low[v] = min(low[v], dfn[u]); } if(dfn[v] == low[v]) { num++; do { u = st[--top]; vis[u] = false; scc[u] = num; }while(u != v); }}bool dfs(int v){ for(int i = 0; i < g[v].size(); i++) { int u = g[v][i]; if(used[u] == false) { used[u] = true; if(match[u] == -1 || dfs(match[u])) { match[u] = v; return true; } } } return false;}void slove(){ for(int i = 1; i <= n; i++) if(dfn[i] == -1) tarjan(i); for(int i = 1; i <= num; i++) g[i].clear(); for(int i = 1; i <= n; i++) for(int j = head[i]; j != -1; j = G[j].next) if(scc[i] != scc[G[j].to]) g[scc[i]].push_back(scc[G[j].to]); int res = 0; memset(match, -1, sizeof match); for(int i = 1; i <= num; i++) { memset(used, 0, sizeof used); if(dfs(i)) res++; } printf("%d\n", num - res);}int main(){ int t, a, b; scanf("%d", &t); while(t--) { init(); scanf("%d%d", &n, &m); for(int i = 0; i < m; i++) { scanf("%d%d", &a, &b); add_edge(a, b); } slove(); } return 0;}
0 0
- HDU 3861The King’s Problem 强连通分量分解 + 二分图最小路径覆盖
- HDU 3861 The King’s Problem (强连通分量缩点+二分图匹配最小路径覆盖)
- HDU 3861 The King’s Problem(强连通+二分图最小路径覆盖)
- HDU - 3861 The King’s Problem(强连通分量+最小路径覆盖)
- hdu 3681The King’s Problem(强连通分量+最小路径覆盖)
- hdu 1269 The King’s Problem(强连通分量+缩点+最小路径覆盖)
- HDU 3861 The King’s Problem 强连通+最小路径覆盖
- hdu 3861 The King’s Problem (强连通+最小路径覆盖)
- hdu 3861 The King’s Problem【强连通Kosaraju+最小路径覆盖】
- hdu3861 The King’s Problem【强连通+最小路径覆盖】
- HDU 3861 The King’s Problem 强连通分量+二分匹配(难)
- HDU 3861 The King’s Problem 连通分量+二分匹配
- 【HDU】3861 The King’s Problem 强连通缩点+有向图最小路径覆盖
- HDOJ 3861 - The King’s Problem tarjan求强联通分量&缩点&有向图最小路径覆盖(匈牙利)
- hdu 3861 The King’s Problem 强连通+二分匹配
- HDU 3861 The King’s Problem 强连通+二分匹配
- HDU 3861 The King’s Problem (强连通+二分匹配)
- The King’s Problem (hdu 3861 强连通缩点+最小路径覆盖)
- 使用开源库zlib压缩和解压文件
- bsoj 2684 【CEOI2004】锯木厂选址
- LeetCode 343. Integer Break(整数分拆)
- yum mysql
- 织梦DedeCms批量提取第一张图片为缩略图
- HDU 3861The King’s Problem 强连通分量分解 + 二分图最小路径覆盖
- Android 中的 Service 全面总结
- 108.PHP输出CSV和EXCEL两种简单的方法
- java基础查找之二分查找
- 初始化列表
- 强引用和弱引用
- armeabi和armeabi-v7a的区别
- 又是二分(避免死循环)
- [Zlib]_[初级]_[使用zlib库压缩文件]