判断DAG图
拓扑排序O(E), bellman O(VE) , 使用邻接表的dfs O(V+E) ,floyd O(N*N*N)
bellman算法只能判断是否存在负环。
所以可以先把权值全部设为-1
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stack>
using namespace std;
const int N = + ;
const int INF = <<;
struct node
{
int u,v,weight;
}g[N+N];
int dist[N];
inline int max(const int &a, const int &b)
{
return a < b ? b : a;
} void init(int n)
{
for(int i=; i<=n; ++i)
{ dist[i] = INF;
}
} void relax(int u, int v, int weight)
{
if(dist[v] > dist[u] + weight)
dist[v] = dist[u] + weight;
}
bool bell(int n, int m)
{
int i,j;
for(i=; i<n; ++i)
for(j=; j<m; ++j)
relax(g[j].u,g[j].v,g[j].weight); for(i=; i<m; ++i)
if(dist[g[i].v] > dist[g[i].u] +g[i].weight)
return true;
return false;
}
int main()
{
int n,m,i,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n== && m==)
break;
init(n);
for(i=; i<m; ++i)
{
scanf("%d%d",&g[i].u,&g[i].v);
g[i].weight = -;//把权值全部改为负的,然后判断是不是存在负环
if(g[i].u==)
dist[g[i].v] = -;
}
if(bell(n,m))
puts("NO");
else
puts("YES");
}
}
枚举起点进行dfs,如果能遇到顶点和起点相同,则存在环
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stack>
using namespace std;
const int N = + ;
vector<int> g[N];
int start;
bool vis[N],flag;
void dfs(int u)
{
if(flag)
return;
for(int i=;i<g[u].size(); ++i)
{
int v = g[u][i];
if(v==start)
{
flag = true;//有环
return;
}
if(!vis[v])
{
vis[v] = true;
dfs(v);
}
}
}
int main()
{
int n,m,i,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n== && m==)
break;
for(i=; i<n; ++i)
g[i].clear();
for(i=; i<m; ++i)
{
scanf("%d%d",&u,&v);
g[u].push_back(v);
}
flag = false;
for(i=; i<n; ++i)
{
memset(vis,,sizeof(vis));
vis[i] = true;
start = i;
dfs(i);
if(flag)
break;
}
if(flag)
puts("NO");
else
puts("YES");
}
}
拓扑排序如果能生成n个顶点序列,那么说明是GAG图
#include <stdio.h>
#include <string.h>
#include <vector>
#include <stack>
using namespace std;
const int N = + ;
vector<int> g[N];
stack<int> st;
int in[N],add[N],cnt;
inline int max(const int &a, const int &b)
{
return a < b ? b : a;
}
void topSort(int n, int m)
{
int u,i;
for(i=; i<=n; ++i)
if(in[i]==)
st.push(i);
while(!st.empty())
{
u = st.top();
cnt++;
st.pop();
for(i=; i<g[u].size(); ++i)
{
--in[g[u][i]];
if(in[g[u][i]]==)
st.push(g[u][i]); }
}
}
void init(int n)
{
cnt = ;
for(int i=; i<=n; ++i)
{
g[i].clear();
add[i] = in[i] = ;
}
}
int main()
{
int n,m,i,u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
if(n== && m==)
break;
init(n);
for(i=; i<m; ++i)
{
scanf("%d%d",&u,&v);
u++;
v++;
g[u].push_back(v);
in[v]++;
}
topSort(n,m);
if(cnt==n)//能生成n个顶点的序列,说明是DAG图
{
puts("YES");
}
else
puts("NO");
}
}
判断DAG图的更多相关文章
- 图论--拓扑排序--判断是否为DAG图
#include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...
- POJ - 3249 Test for Job (在DAG图利用拓扑排序中求最长路)
(点击此处查看原题) 题意 给出一个有n个结点,m条边的DAG图,每个点都有权值,每条路径(注意不是边)的权值为其经过的结点的权值之和,每条路径总是从入度为0的点开始,直至出度为0的点,问所有路径中权 ...
- 图结构练习——判断给定图是否存在合法拓扑序列(dfs算法(第一个代码),邻接矩阵(前两个代码),邻接表(第三个代码))
sdut 2140 图结构练习——判断给定图是否存在合法拓扑序列 Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^ 题目描述 给定一个有向图 ...
- 有标号的DAG图计数1~4
前言 我什么都不会,菜的被关了起来. 有标号的DAG图I Solution 考虑递推,设\(f_i\)表示i个点的答案,显然这个东西是可以组合数+容斥递推? 设\(f_i\)表示i个点的答案,我们考虑 ...
- SDUT OJ 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
数据结构实验之图论十:判断给定图是否存在合法拓扑序列 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Prob ...
- Tarjan缩点+DAG图dp
题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...
- 《编译原理》画 DAG 图与求优化后的 4 元式代码- 例题解析
<编译原理>画 DAG 图与求优化后的 4 元式代码- 例题解析 DAG 图(Directed Acylic Graph)无环路有向图 (一)基本块 基本块是指程序中一顺序执行的语句序列, ...
- 洛谷 P2656 (缩点 + DAG图上DP)
### 洛谷 P2656 题目链接 ### 题目大意: 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖 ...
- SDUT-2140_判断给定图是否存在合法拓扑序列
数据结构实验之图论十:判断给定图是否存在合法拓扑序列 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给定一个有向图,判 ...
随机推荐
- 【PAT】1035. Password (20)
题目:http://pat.zju.edu.cn/contests/pat-a-practise/1035 分析:简单题.直接搜索,然后替换,不会超时,但是应该有更好的办法. 题目描述: To pre ...
- android打包apk时混淆遇到的问题
android打包apk的时候一般会选择混淆,而在eclipse中常使用的是proguard来混淆.有很多时候引用了第三方包的时候会导致打包不成功,或者打包成功不能运行的情况. 首先看看正常的prog ...
- wiki 3143 二叉树的前序、中序及后序遍历
先序遍历:訪问根.遍历左子树.遍历右子树,简称:DLR. 中序遍历:遍历左子树,訪问根,遍历右子树,简称:LDR. 后序遍历:遍历左子树,遍历右子树.訪问根.简称:LRD. 数组搞的: #pragma ...
- crontab linux
第1列分钟1-59第2列小时1-23(0表示子夜)第3列日1-31第4列月1-12第5列星期0-6(0表示星期天)第6列要运行的命令 下面是crontab的格式:分 时 日 月 星期 要运行的命令 这 ...
- sqlserver 操作技巧
1.将不同库中的一张表数据导入到另外一张表中去 ① 两张表多存在实体,两表的字段相同,字段的顺序相同的话. insert into 表B select * from 表A ② 两张表多存在实体,两表的 ...
- 引用类中的enum
引用类中的enum 引用类中的enum,需要加类的域class_name::value_in_enum_name 点击(此处)折叠或打开 #include <stdio.h> #inclu ...
- 例3.1 猜猜数据结构 UVa11995
1.标题叙述性说明:点击打开链接 2.解题思路:据来推測一种可能的数据结构,备选答案有"栈,队列.优先队列".结果也可能都不是或者不确定. STL中已经有这三种数据结构了,因此直接 ...
- 初窥Linux 之 区分硬连接和软连接
一.Linux下的两种连接文件及创建方式 在Linux下面的连接文件有两种——软连接和硬连接,虽然都是连接文件,但两者却有很大的区别.一种是类似于Windows的快捷方式功能的文件(或目录),这种连接 ...
- 15个最好的HTML5前端响应式框架(2014)
文中的多个框架基于SASS创建,SCSS是一种比LESS更简洁的样式表编程语言,它能够编绎成CSS,可复用CSS代码,声明变量,甚至是函数,类Ruby/Python的语法.參见: LESS vs SA ...
- POJ3313 【随便写了个spfa就一A了,嗨皮】
我顺便明白了....英文题意理解其实好大一部分还是靠感觉,然后自己猜题意,试题意. 你要是纠结于英文你就跪了. #include <iostream> #include <cstdi ...