题意:有 n 个点,m 条边的有向图,需要将这些点分成多个块,要求:如果两点之间有路径能够互相到达,那么这两个点必须分在同一块;在同一块内的任意两点相互之间至少要有一条路径到达,即 u 到达 v 或 v 到达 u;每个点都只能存在于单独一个块内。问最少需要划分多少块。

首先,对于如果两点之间能够相互到达则必须在同一块,其实也就是在同一个强连通分量中的点必须在同一块中,所以首先就是强连通缩点。然后在同一块内的任意两点之间要有一条路,那么其实就是对于一块内的强连通分量,至少要有一条路径贯穿所有分量。而这一条路径上的所有强连通分量就可以构成同一块。那么其实我们就是需要找出最少的这样的路径将所有点全部覆盖一遍,就是做一遍最小路径覆盖。

最小路径覆盖数=点数-拆点后的最大匹配数。

 #include<stdio.h>
#include<string.h>
#include<stack>
#include<queue>
using namespace std; const int maxn=;
const int maxm=2e5+; int head[][maxn],point[][maxm],nxt[][maxm],size[];
int n,t,scccnt;
int stx[maxn],low[maxn],scc[maxn];
int vis[maxn],match[maxn];
stack<int>S; void init(){
memset(head,-,sizeof(head));
size[]=size[]=;
} void add(int a,int b,int c=){
point[c][size[c]]=b;
nxt[c][size[c]]=head[c][a];
head[c][a]=size[c]++;
} void dfs(int s){
stx[s]=low[s]=++t;
S.push(s);
for(int i=head[][s];~i;i=nxt[][i]){
int j=point[][i];
if(!stx[j]){
dfs(j);
low[s]=min(low[s],low[j]);
}
else if(!scc[j]){
low[s]=min(low[s],stx[j]);
}
}
if(low[s]==stx[s]){
scccnt++;
while(){
int u=S.top();S.pop();
scc[u]=scccnt;
if(s==u)break;
}
}
} void setscc(){
memset(stx,,sizeof(stx));
memset(scc,,sizeof(scc));
t=scccnt=;
for(int i=;i<=n;++i)if(!stx[i])dfs(i);
for(int i=;i<=n;++i){
for(int j=head[][i];~j;j=nxt[][j]){
int k=point[][j];
if(scc[i]!=scc[k]){
add(scc[i],scc[k]+scccnt,);
}
}
}
} int dfs1(int k){
for(int i=head[][k];~i;i=nxt[][i]){
if(!vis[point[][i]]){
int p=point[][i];
vis[p]=;
if(match[p]==-||dfs1(match[p])){
match[p]=k;
return ;
}
}
}
return ;
} int main(){
int T;
scanf("%d",&T);
while(T--){
int m;
scanf("%d%d",&n,&m);
init();
while(m--){
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
}
setscc();
int ans=;
memset(match,-,sizeof(match));
for(int i=;i<=*scccnt;++i){
memset(vis,,sizeof(vis));
if(dfs1(i)==)ans++;
}
printf("%d\n",scccnt-ans);
}
return ;
}

hdu3861 强连通+最小路径覆盖的更多相关文章

  1. 【HDU3861 强连通分量缩点+二分图最小路径覆盖】

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意:一个有向图,让你按规则划分区域,要求划分的区域数最少. 规则如下:1.有边u到v以及有 ...

  2. hdu3861 强连通分量缩点+二分图最最小路径覆盖

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  3. hdu3861 The King’s Problem 强连通缩点+DAG最小路径覆盖

    对多校赛的题目,我深感无力.题目看不懂,英语是能懂的,题目具体的要求以及需要怎么做没有头绪.样例怎么来的都不明白.好吧,看题解吧. http://www.cnblogs.com/kane0526/ar ...

  4. HDU 3861 The King’s Problem 最小路径覆盖(强连通分量缩点+二分图最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 最小路径覆盖的一篇博客:https://blog.csdn.net/qq_39627843/ar ...

  5. Light OJ 1406 Assassin`s Creed 状态压缩DP+强连通缩点+最小路径覆盖

    题目来源:Light OJ 1406 Assassin`s Creed 题意:有向图 派出最少的人经过全部的城市 而且每一个人不能走别人走过的地方 思路:最少的的人能够走全然图 明显是最小路径覆盖问题 ...

  6. HDU 3861 The King’s Problem(强连通分量+最小路径覆盖)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861 题目大意: 在csdn王国里面, 国王有一个新的问题. 这里有N个城市M条单行路,为了让他的王国 ...

  7. HDU 3861 The King's Problem(强连通分量缩点+最小路径覆盖)

    http://acm.hdu.edu.cn/showproblem.php?pid=3861 题意: 国王要对n个城市进行规划,将这些城市分成若干个城市,强连通的城市必须处于一个州,另外一个州内的任意 ...

  8. HDU 3861 The King’s Problem 强连通分量 最小路径覆盖

    先找出强连通分量缩点,然后就是最小路径覆盖. 构造一个二分图,把每个点\(i\)拆成两个点\(X_i,Y_i\). 对于原图中的边\(u \to v\),在二分图添加一条边\(X_u \to Y_v\ ...

  9. hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. 到目前为止,Linux下最完整的Samba服务器配置攻略 (转)

    http://blog.chinaunix.net/uid-23069658-id-3142052.html 安装平台为UBUNTU 14.04,直接软件中心安装samba, service smb ...

  2. Oracle Database 11g express edition

    commands : show sys connect sys as sysdba or connect system as sysdba logout or disc clear screen or ...

  3. 每天学一点JAVA

    1.JAVA的反射机制 在运行时判断任意一个对象所属的类:在运行时构造任意一个类的对象:在运行时判断任意一个类所具有的成员变量和方法:在运行时调用任意一个对象的方法:生成动态代理. 2.关于ARRAY ...

  4. dialog参数、方法以及事件

    参数(options) DOM方式初始化dialog的,推荐使用集合属性data-options定义参数,如果使用data属性定义参数,注意转换成对应的名称. 名称 类型 默认值 描述 id stri ...

  5. Android模拟器配置选项说明

    Memory Options是模拟器的运行内存大小,类比电脑内存大小,就是在设置->应用程序中,正在运行标签页下面显示的那个大小Internal storage是模拟器内置存储空间大小,用于存放 ...

  6. Centos使用key登录验证

    1. 新建用户lsyw 设置密码 #useradd lsyw #passwd lsyw 2. 测试新建用户可以登录 3. 修改root登录密码为通用root密码,测试用新密码登录是否成功 0!B2pj ...

  7. SDIO接口

    SDIO卡是在SD内存卡接口的基础上发展起来的接口,SDIO接口兼容以前的SD内存卡,并且可以连接SDIO接口的设备,目前根据SDIO协议的SPEC,SDIO接口支持的设备总类有蓝牙,网卡,电视卡等. ...

  8. C++11 std::copy

    这个函数并不是简单的 while(first != last) { *result = *first; result++; first++; } 事实上这种写法是最具普适性的,值要求inputIter ...

  9. Java中的接口与抽象类

    抽象类很简单,就是多了个abstract关键字,可以有(也可以没有)只声明不定义的方法.不能实例化该类. 接口比较特殊: 无论你加不加public,接口中声明的方法都是public的,还有无论你加不加 ...

  10. jQuery轮播图

    yii2 轮播 样式: <style type="text/css"> *{margin:0;padding:0} body{margin:50px} li{list- ...