poj2762 判断一个图中任意两点是否存在可达路径 也可看成DAG的最小覆盖点是否为1
Going from u to v or from v to u?
| Time Limit: 2000MS | Memory Limit: 65536K | |
| Total Submissions: 17993 | Accepted: 4816 |
Description
Input
The first line for each case contains two integers n, m(0 < n < 1001,m < 6000), the number of rooms and corridors in the cave. The next m lines each contains two integers u and v, indicating that there is a corridor connecting room u and room v directly.
Output
Sample Input
1
3 3
1 2
2 3
3 1
Sample Output
Yes 题目大意就是给你张图,问你是否任意两点u,v 可以从u到v或者从v到u
两种解法 先贴拓扑的
另外有些数据
1
3 2
1 2
3 2 1
3 3
1 2
1 3
2 3
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=;
const int M=;
int head[N],dfn[N],in[N],low[N],bl[N],q[N];
int tot,cnt,scnt,n,m,l;
bool instack[N];
bool adj[N][N];
struct node{
int u,to,next;
}e[M<<];
void init(){
memset(dfn,,sizeof(dfn));
memset(instack,,sizeof(instack));
memset(in,,sizeof(in));
memset(head,-,sizeof(head));
memset(adj,,sizeof(adj));
l=tot=cnt=scnt=;
}
void add(int u,int v){
e[tot].u=u;e[tot].to=v;e[tot].next=head[u];head[u]=tot++;
}
void Tajan(int u){
instack[u]=;
q[l++]=u;
low[u]=dfn[u]=++cnt;
for(int i=head[u];i+;i=e[i].next){
int v=e[i].to;
if(!dfn[v]) {
Tajan(v);
low[u]=min(low[u],low[v]);
}
else if(instack[v]&&low[u]>dfn[v]) low[u]=dfn[v];
}
if(low[u]==dfn[u]){
int t;
++scnt;
do{
t=q[--l];
instack[t]=;
bl[t]=scnt;
}while(t!=u);
}
}
bool Ju(int u){
while(scnt--){
int cont=;
for(int i=head[u];i+;i=e[i].next){
int v=e[i].to;
--in[v];
if(in[v]==) {
cont++;u=v;
}
}
if(cont>) return ;
}
return ;
}
int main(){
int T,u,v;
for(scanf("%d",&T);T--;){
scanf("%d%d",&n,&m);
init();
for(int i=;i<=m;++i){
scanf("%d%d",&u,&v);
add(u,v);
}
for(int i=;i<=n;++i)
if(!dfn[i]) Tajan(i);
memset(head,-,sizeof(head));
for(int i=;i<tot;++i){
u=e[i].u,v=e[i].to;
if(bl[u]==bl[v]||adj[u][v]) continue;
else {
adj[bl[u]][bl[v]]=; // 注意这里
add(bl[u],bl[v]);
++in[bl[v]];
}
}
int cont=,k;
for(int i=;i<=scnt;++i)
if(!in[i]) {++cont;k=i;}
if(cont>) {puts("No");continue;}
else {
if(Ju(k)) puts("Yes");
else puts("No");
}
}
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm> using namespace std; const int MAXN = ;
const int MAXM = ; struct Edge{
int to, next;
}edge[MAXM]; int head[MAXN], tot;
int Low[MAXN], DFN[MAXN], Stack[MAXN], Belong[MAXN];
int Index, top;
int scc;
bool Instack[MAXN];
int num[MAXN];
int n, m; void init() {
tot = ;
memset(head, -, sizeof(head));
} void addedge(int u, int v) {
edge[tot].to = v;
edge[tot].next = head[u];
head[u] = tot++;
} void Tarjan(int u) {
int v;
Low[u] = DFN[u] = ++Index;
Stack[top++] = u;
Instack[u] = true;
for (int i = head[u]; i != -; i = edge[i].next) {
v = edge[i].to;
if (!DFN[v]) {
Tarjan(v);
if (Low[u] > Low[v]) Low[u] = Low[v];
}
else if (Instack[v] && Low[u] > DFN[v])
Low[u] = DFN[v];
}
if (Low[u] == DFN[u]) {
scc++;
do {
v = Stack[--top];
Instack[v] = false;
Belong[v] = scc;
num[scc]++;
} while (v != u);
}
} void solve() {
memset(Low, , sizeof(Low));
memset(DFN, , sizeof(DFN));
memset(num, , sizeof(num));
memset(Stack, , sizeof(Stack));
memset(Instack, false, sizeof(Instack));
Index = scc = top = ;
for (int i = ; i <= n; i++)
if (!DFN[i])
Tarjan(i);
} vector<int> g[MAXN];
int linker[MAXN], used[MAXN]; bool dfs(int u) {
for (int i = ; i < g[u].size(); i++) {
int v = g[u][i];
if (!used[v]) {
used[v] = ;
if (linker[v] == - || dfs(linker[v])) {
linker[v] = u;
return true;
}
}
}
return false;
} int hungary() {
int res = ;
memset(linker, -, sizeof(linker));
for (int i = ; i <= scc; i++) {
memset(used, , sizeof(used));
if (dfs(i)) res++;
}
return (scc - res)==;
} int main() {
int cas;
scanf("%d", &cas);
while (cas--) {
scanf("%d%d", &n, &m);
init();
int u, v;
for (int i = ; i < m; i++) {
scanf("%d%d", &u, &v);
addedge(u, v);
}
solve(); for (int i = ; i <= scc; i++) g[i].clear();
for (int u = ; u <= n; u++) {
for (int i = head[u]; i != -; i = edge[i].next) {
int v = edge[i].to;
if (Belong[u] != Belong[v])
g[Belong[u]].push_back(Belong[v]);
}
}
if(hungary()) puts("Yes");
else puts("No");
}
return ;
}
poj2762 判断一个图中任意两点是否存在可达路径 也可看成DAG的最小覆盖点是否为1的更多相关文章
- Floyd-Warshall求图中任意两点的最短路径
原创 除了DFS和BFS求图中最短路径的方法,算法Floyd-Warshall也可以求图中任意两点的最短路径. 从图中任取两点A.B,A到B的最短路径无非只有两种情况: 1:A直接到B这条路径即是最短 ...
- javascript实现有向无环图中任意两点最短路径的dijistra算法
有向无环图 一个无环的有向图称做有向无环图(directed acycline praph).简称DAG 图.DAG 图是一类较有向树更一般的特殊有向图, dijistra算法 摘自 http://w ...
- C#实现如何判断一个数组中是否有重复的元素 返回一个数组升序排列后的位置信息--C#程序举例 求生欲很强的数据库 别跟我谈EF抵抗并发,敢问你到底会不会用EntityFramework
C#实现如何判断一个数组中是否有重复的元素 如何判断一个数组中是否有重复的元素 实现判断数组中是否包含有重复的元素方法 这里用C#代码给出实例 方法一:可以新建一个hashtable利用hasht ...
- 【C++】判断一个图是否有环 无向图 有向图(转载)
没有找到原文出处,请参考一下链接: http://www.cnblogs.com/hiside/archive/2010/12/01/1893878.html http://topic.csdn.ne ...
- C#实现如何判断一个数组中是否有重复的元素
如何判断一个数组中是否有重复的元素 实现判断数组中是否包含有重复的元素方法 这里用C#代码给出实例 方法一:可以新建一个hashtable利用hashtable的Contains方法进行查找 /// ...
- Python判断一个字符串中是否存在多个子串中的一个
在使用python的开发过程中,常常需要判断,字符串中是否存在子串的问题, 但判断一个字符串中是否存在多个字串中的一个时,如if (a or b) in c或者if x contains a|b|c| ...
- c c++怎么判断一个字符串中是否含有汉字
c c++怎么判断一个字符串中是否含有汉字 (2013-02-05 10:44:23) 转载▼ #include #include int main() { char sztext[] = ...
- C#判断一个类中有无"指定名称"的方法
C#中可以通过反射分析元数据来解决这个问题,示例代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 2 ...
- javascript 写一段代码,判断一个字符串中出现次数最多的字符串,并统计出现的次数
javascript 写一段代码,判断一个字符串中出现次数最多的字符串,并统计出现的次数 function test(){ var bt = document.getElementById(" ...
随机推荐
- SpringCloudAlibaba实战教程系列
一.简介 Spring Cloud Alibaba 致力于提供微服务开发的一站式解决方案.此项目包含开发分布式应用服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开 ...
- 01-Vue初学习
1. Vue下载 (1)网址:https://cn.vuejs.org/v2/guide/installation.html (2)点击开发版本,下载完成是一个 Vue.js 2. 使用 (1)创建文 ...
- mpvue开发微信小程序之时间+日期选择器
最近在做微信小程序,技术栈为mpvue+iview weapp组件库. 因项目需求,要用到日期+时间选择器,iview组件库目前还未提供时间日期选择器的组件,小程序官方组件日期时间也是分开的,在简书上 ...
- THU OS
前言 最近在学清华的OS课程,实验课做的真厉害. 我们的操作系统课就是写一个系统调用,改下进程软中断通信的代码,代码量不足500...清华是借鉴MIT的课,实验课都是做一个完整的小型操作系统. 一共8 ...
- Jmeter 插件图表分析
1.jp@gc - Actiive Threads Over Time:不同时间的活动用户数量展示(图表) 当前的时间间隔是1毫秒,在 setting 中可以设置时间间隔以及其他的参数,右击可以导出 ...
- Jenkins 部署(基于 Linux)
1.安装 JDK 我不列出来了,自行百度 java -version 2.安装 tomcat (1)创建目录 tomcat8 (2)导入 tomcat 文件到 tomcat8 录中并解压 (3)启动 ...
- Android APK 重签名
对APK 进行在线 加固后,Apk体积一般会变大,而且Apk会无法直接安装,因为缺少了你的签名.是的,你需要对这个Apk进行重签名. 如何重签名 重签名的方法,一般来说,有两种,第一种是用JDK自带的 ...
- Java——Java是什么一门什么语言
解释型语言 源代码不能直接翻译成机器语言,而是先翻译成中间代码,再由解释器对中间代码进行解释运行: 程序不需要编译,程序在运行时才翻译成机器语言,每执行一次都要翻译一次: 解释性语言代表:Python ...
- 这是一篇每个人都能读懂的最小生成树文章(Kruskal)
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法和数据结构专题的第19篇文章,我们一起来看看最小生成树. 我们先不讲算法的原理,也不讲一些七七八八的概念,因为对于初学者来说,看到 ...
- WCF学习(二)
WCF通道模型 绑定的本质是一个配置好的通道栈,为了方便程序员专著与业务逻辑,WCF提高了一系列常用绑定.随后会有相应的自定义通道栈代码 无论交互的另一方具体位置在哪里,WCF都会为消息的发送和接收建 ...