题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3861

题意:输入t,表示t个样例。接下来每个样例第一行有两个数n,m表示点数和有向边的数量,接下来输入m条有向边,现在要我们把点划分成最少的块,每个块里面的点两两之间要至少有一条有向边可以从其中一个点到另一个点。

思路:分成的区域里面两个点之间至少要有一个点可以到达另一个点,并且要区域数最少,那么就是求最小路径覆盖,但是要求最小路径覆盖的前提是要是无环,所以我们要先用tarjan算法缩点,然后在在缩完点的图上面建一个二分图来求最小路径覆盖。

最小路径覆盖我是刚刚接触,推荐博客:https://www.cnblogs.com/jianglangcaijin/p/5989907.html

这里我用的是链式前向星,没有用vector,代码长了一点

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
#include<stack>
#include<cmath>
#include<vector>
#include<set>
#include<cstdio>
#include<string>
#include<deque>
using namespace std;
typedef long long LL;
#define eps 1e-8
#define INF 0x3f3f3f3f
#define maxn 5005
struct node{
int v,next;
}edge1[maxn**],edge2[maxn**];
int head1[maxn],dfn[maxn],low[maxn],s[maxn],color[maxn];
int head2[maxn],pre[maxn*];
bool vis[maxn*];
int top,cnt1,time,color_num;
int cnt2,ans;
int n,m,k,t;
void init()
{
memset(head1,-,sizeof(head1));
memset(dfn,,sizeof(dfn));
memset(vis,false,sizeof(vis));
memset(pre,-,sizeof(pre));
memset(head2,-,sizeof(head2));
cnt1=time=color_num=top=;
cnt2=ans=;
}
void addedge1(int u,int v)//第一次建图添加边
{
edge1[++cnt1].v=v;
edge1[cnt1].next=head1[u];
head1[u]=cnt1;
}
void addedge2(int u,int v)//第二次建图添加边
{
edge2[++cnt2].v=v;
edge2[cnt2].next=head2[u];
head2[u]=cnt2; }
void DFS(int u)//缩点(染色)
{
low[u]=dfn[u]=++time;
vis[u]=true;
s[top++]=u;
for(int i=head1[u];i!=-;i=edge1[i].next)
{
int v=edge1[i].v;
if(!dfn[v])
{
DFS(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v])
low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u])
{
color_num++;
int v;
do{
v=s[--top];
vis[v]=false;
color[v]=color_num;
}while(u!=v);
}
}
void tarjan()
{
for(int i=;i<=n;i++)
{
if(!dfn[i])
DFS(i);
}
}
void rebuild()
{
for(int i=;i<=n;i++)
{
for(int j=head1[i];j!=-;j=edge1[j].next)
{
int v=edge1[j].v;
int a=color[i];
int b=color[v];
if(a!=b)
addedge2(a,b);//建一个二分图
//最小路径覆盖就是点数减最大匹配,注意前提是图里面无环,所以要先缩点
}
}
}
bool hungry_DFS(int u)//求最大匹配
{
for(int i=head2[u];i!=-;i=edge2[i].next)
{
int v=edge2[i].v;
if(vis[v])
continue;
vis[v]=true;
if(pre[v]==-||hungry_DFS(pre[v]))
{
pre[v]=u;
return true;
}
}
return false;
}
void hungry()
{
for(int i=;i<=color_num;i++)
{
memset(vis,false,sizeof(vis));
if(hungry_DFS(i))
ans++;
}
printf("%d\n",color_num-ans);//注意这里是缩点之后的点数减最大匹配数
}
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
int u,v;
for(int i=;i<=m;i++)
{
scanf("%d%d",&u,&v);
addedge1(u,v);//第一次建图
}
tarjan();//缩点
rebuild();//第二次建图
hungry();//求最大匹配
}
return ;
}

缩点+最小路径覆盖 hdu 3861的更多相关文章

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

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

  2. 【HDOJ3861】【Tarjan缩点+最小路径覆盖】

    http://acm.hdu.edu.cn/showproblem.php?pid=3861 The King’s Problem Time Limit: 2000/1000 MS (Java/Oth ...

  3. Light OJ 1429 Assassin`s Creed (II) BFS+缩点+最小路径覆盖

    题目来源:Light OJ 1429 Assassin`s Creed (II) 题意:最少几个人走全然图 能够反复走 有向图 思路:假设是DAG图而且每一个点不能反复走 那么就是裸的最小路径覆盖 如 ...

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

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

  5. Graph_Master(连通分量_C_Trajan缩点+最小路径覆盖)

    hdu_3861 题目大意:给定一张有向图,若<u,v>可达(u可以走到v,或者 v可以走到u),则<u,v>需被划分在统一城邦,问最小划分城邦数. 题解:比较裸的题,可以看出 ...

  6. 最小路径覆盖 hdu 1151 hdu 3335

    Air Raid Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  7. HDU 3861 The King’s Problem(tarjan缩点+最小路径覆盖:sig-最大二分匹配数,经典题)

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

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

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

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

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

随机推荐

  1. sql server导入excel数据

    1.sql导入工具,数据源选择 microsoft excel 2.有odbc配置过的连接excel或其他数据库,都可以选择netframwork data provider for odbc,在ds ...

  2. WebService与RESTful WebService

    Manual Instruction Document Web Service JAX-WS & JAX-RS Author: Liu Xiang Date: 2018/01/12 1. Su ...

  3. 微信、企业微信和支付窗 SDK 三合一,JeeWx-api 1.2.0 版本发布

    摘要: JEEWX-API 是第一款JAVA版微信极速SDK,同时集成企业微信SDK,支付窗SDK,可以快速的基于她进行微信公众号.企业微信.支付窗应用开发.基于 jeewx-api 开发可以立即拥有 ...

  4. mysql Lock wait timeout exceeded; try restarting transaction解决

    前面已经了解了InnoDB关于在出现锁等待的时候,会根据参数innodb_lock_wait_timeout的配置,判断是否需要进行timeout的操作,本文档介绍在出现锁等待时候的查看及分析处理: ...

  5. Django下的templates 和 static静态文件

    如果Django顶层目录中没有templates的话,就自己新建一个Directory ,这个文件是存放html文件的 1)如果在views里面用render(request,"" ...

  6. (笨方法)利用stat函数实现ls -l filename

    学习了一段时间的Linux了,但是我感觉我做不出来啥子,后头选择利用系统IO函数实现命令,先从ls走起吧.先来看看ls -l filename给我们显示了什么吧 : 可以看到,一共八项:文件类型.用户 ...

  7. android手机 解锁bootloader 刷recovery 线刷rom 卡刷rom

    1 解锁bootloader 为手机安装官方驱动 按相应的组合键使手机进入fastboot模式 执行命令fastboot oem unlock 123456 (123456为厂家提供的解锁码) 手机重 ...

  8. git-04 同意分支合并

    https://blog.csdn.net/boysky0015/article/details/78185879/

  9. Hibernate学习笔记3.1(Hibernate关系映射)

    主要指对象之间的关系 1.一对一关联 一对一单项外键关联 比如说一夫一妻 Wifi.java package com.bjsxt.hibernate; import javax.persistence ...

  10. 通过AI自学习,Google让Pixel 3的人像模式更优秀

    通过AI自学习,Google让Pixel 3的人像模式更优秀 Link: https://news.cnblogs.com/n/613720/ 虽然双摄手机已经在市场上普及,其所带来的人像模式.多倍变 ...