题目链接: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. HTML页面过渡效果大全

    IE要求: 在IE5.5及以上版本的浏览器中.启用网页过渡效果 默认情况下都已经启用了,如果需要手动启用则只需在Internet选项中: Advanced(高级) - Browsing(浏览) - E ...

  2. 高并发和大流量解决方案--CND加速

    CDN全称 Content Delivery Network,即内容分发网络.其基本思路是尽可能避开互联网上有可能影响数据传输速度和稳定性的瓶颈和环节,使内容传输的更快.更稳定.通过在网络各处放置节点 ...

  3. Appium -选择、操作元素3

    UI Automator API定位 id .class name.acessibility id.xpath底层都是通过UI Automator API定位,UI Automator测试框架提供了一 ...

  4. WebAssembly相关

    git搜索:https://github.com/search?q=WebAssembly 相关demo:https://github.com/jpmorganchase/perspective we ...

  5. Java IO中转换流的作用

    在<Java网络编程>中,有这样一段话: ”Reader和Writer最重要的子类是InputStreamReader和OutputStreamWriter类. InputStreamRe ...

  6. openwrt手动wifi设成client模式[笔记]

    说明:刚刷好的OPENWRT,默认是不带luci-web管理的,所以得手工SSH或TELNET上去改WIFI模式,以便通过WIFI连到现有的ROUTER去下载安装luci...: root@OpenW ...

  7. 吴裕雄 28-MySQL 序列使用

    MySQL序列是一组整数:1, 2, 3, ...,由于一张数据表只能有一个字段自增主键, 如果你想实现其他字段也实现自动增加,就可以使用MySQL序列来实现 使用AUTO_INCREMENTMySQ ...

  8. JVM G1GC参数配置

    https://www.oracle.com/technetwork/articles/java/g1gc-1984535.html         主要这两个参数需要设置下,ParallelGCTh ...

  9. SpringBoot @Aspect

    1.添加maven依赖注解 <!--springBoot的aop--> <dependency> <groupId>org.springframework.boot ...

  10. spring boot 微服务例子一

    package com.example.hello.demo; import org.springframework.boot.SpringApplication;import org.springf ...