hdu-3861(强连通图缩点+二分图最小路径覆盖)
来源:互联网 发布:ubuntu 16进制编辑器 编辑:程序博客网 时间:2024/06/05 00:11
题目大意:一个有向图,让你按规则划分区域,要求划分的区域数最少。
规则如下:1、有边u到v以及有边v到u,则u,v必须划分到同一个区域内。2、一个区域内的两点至少要有一方能到达另一方。3、一个点只能划分到一个区域内。
解题思路:根据规则1可知必然要对强连通分量进行缩点,缩点后变成了一个弱连通图。根据规则2、3可知即是要求图的最小路径覆盖。
定义:
最小路径覆盖:在图中找一些路径(路径数最少),使之覆盖了图中所有的顶点,且每个顶点有且仅和一条路径有关联。
最小顶点覆盖:在图中找一些点(顶点数最少),使之覆盖了图中所有的边,每条边至少和一个顶点有关联。
二分图:最小顶点覆盖=最大匹配数。
最小路径覆盖=顶点数-最大匹配数。
#include <iostream>#include <cstdio>#include <vector>#include <algorithm>#include <cstring>using namespace std;const int maxn=55555;int dfn[maxn], low[maxn], stack[maxn], belong[maxn], visit[maxn], match[maxn];bool instack[maxn];int top, scnt, Index, n, m, T;vector<int>vt[maxn];struct Node{ int u, v;//有向边u->v}f[2*maxn];void Init_tarjan(){ top=scnt=Index=0; for(int i=1; i<=n; i++) dfn[i]=low[i]=instack[i]=0;}void tarjan(int u)//求该有向图的强连通分量{ stack[++top]=u; dfn[u]=low[u]=++Index;//DFN(u)为节点u搜索的次序编号(时间戳), instack[u]=1; //Low(u)为u或u的子树能够追溯到的最早的栈中节点的次序号 for(int i=0; i<vt[u].size(); i++) { int v=vt[u][i]; if(!dfn[v]) { tarjan(v); low[u]=min(low[u],low[v]); } else if(instack[v]) { low[u]=min(low[u],dfn[v]); } } if(low[u]==dfn[u]) { int v; scnt++; do { v=stack[top--]; instack[v]=0; belong[v]=scnt;//scnt值为强连通分量个数 } while(u!=v); }}bool find(int u)//是否能形成匹配{ for(int i=0; i<vt[u].size(); i++) { int v=vt[u][i]; if(!visit[v]) { visit[v]=1; if(match[v]==-1||find(match[v])) { match[v]=u; return true; } } } return false;}int hungary()//二分图最大匹配{ int cnt=0; memset(match,-1,sizeof(match)); for(int i=1; i<=scnt; i++) { for(int j=1; j<=scnt; j++) visit[j]=0; if(find(i)) cnt++; } return cnt;}int main(){ cin >> T; while(T--) { cin >> n >> m; for(int i=0; i<=n; i++) vt[i].clear(); for(int i=0; i<m; i++) { scanf("%d%d",&f[i].u,&f[i].v); vt[f[i].u].push_back(f[i].v); } Init_tarjan(); for(int i=1; i<=n; i++) if(!dfn[i]) tarjan(i); for(int i=0; i<=n; i++) vt[i].clear(); for(int i=0; i<m; i++) { int u=belong[f[i].u], v=belong[f[i].v]; if(u==v) continue; vt[u].push_back(v);//缩点,成为弱连通图 } int ans=hungary(); cout << scnt-ans <<endl; } return 0;}
0 0
- hdu-3861(强连通图缩点+二分图最小路径覆盖)
- HDU 3861 The King’s Problem(强连通+二分图最小路径覆盖)
- 强连通+最小路径覆盖 hdu 3861
- HDU 3861The King’s Problem 强连通分量分解 + 二分图最小路径覆盖
- hdu 3861 强连通分量缩点+二分匹配求最小路径覆盖
- HDU 3861 The King’s Problem (强连通分量缩点+二分图匹配最小路径覆盖)
- hdu 3861 The King’s Problem (强连通+最小路径覆盖)
- 强连通+最小路径覆盖
- HDU tarjan算法模版 强连通分量+最小路径覆盖
- HDU 3861 The King’s Problem 强连通+最小路径覆盖
- hdu 3861 (强连通分量+最小路径覆盖)题意有些怪
- HDU - 3861 The King’s Problem(强连通分量+最小路径覆盖)
- hdu 3861 The King’s Problem【强连通Kosaraju+最小路径覆盖】
- hdu 1269 The King’s Problem(强连通分量+缩点+最小路径覆盖)
- HDU3861(强连通+最小覆盖路径)
- hdu 4160 二分图最小路径覆盖
- hdu 1151二分图最小路径覆盖
- hdu 1151 二分图最小路径覆盖
- 怎么找回不小心删除的chrom书签,怎么找到备份书签。
- Android--资源目录
- iOS可执行文件瘦身方法
- java5线程并发库的应用(九)
- 10-1. 在字符串中查找指定字符(15)
- hdu-3861(强连通图缩点+二分图最小路径覆盖)
- LeetCode:Merge Sorted Array
- LeetCode --- 29. Divide Two Integers
- Spring(五)使用Spring集成MyBatis
- 06-1. 简单计算器(20)
- LeetCode --- 30. Substring with Concatenation of All Words
- cocos2d-x 3.3 按钮添加和事件(CCControlButton)
- Red-Black Tree 红黑树
- Qt5学习笔记(6)——下拉列表框QComboBox类