拓扑排序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图的更多相关文章

  1. 图论--拓扑排序--判断是否为DAG图

    #include<cstdio> #include<cstring> #include<vector> #include<queue> using na ...

  2. POJ - 3249 Test for Job (在DAG图利用拓扑排序中求最长路)

    (点击此处查看原题) 题意 给出一个有n个结点,m条边的DAG图,每个点都有权值,每条路径(注意不是边)的权值为其经过的结点的权值之和,每条路径总是从入度为0的点开始,直至出度为0的点,问所有路径中权 ...

  3. 图结构练习——判断给定图是否存在合法拓扑序列(dfs算法(第一个代码),邻接矩阵(前两个代码),邻接表(第三个代码))

    sdut 2140 图结构练习——判断给定图是否存在合法拓扑序列 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述  给定一个有向图 ...

  4. 有标号的DAG图计数1~4

    前言 我什么都不会,菜的被关了起来. 有标号的DAG图I Solution 考虑递推,设\(f_i\)表示i个点的答案,显然这个东西是可以组合数+容斥递推? 设\(f_i\)表示i个点的答案,我们考虑 ...

  5. SDUT OJ 数据结构实验之图论十:判断给定图是否存在合法拓扑序列

    数据结构实验之图论十:判断给定图是否存在合法拓扑序列 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Prob ...

  6. Tarjan缩点+DAG图dp

    题目背景 缩点+DP 题目描述 给定一个n个点m条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个点,但是,重复经过的点,权值只 ...

  7. 《编译原理》画 DAG 图与求优化后的 4 元式代码- 例题解析

    <编译原理>画 DAG 图与求优化后的 4 元式代码- 例题解析 DAG 图(Directed Acylic Graph)无环路有向图 (一)基本块 基本块是指程序中一顺序执行的语句序列, ...

  8. 洛谷 P2656 (缩点 + DAG图上DP)

    ### 洛谷 P2656 题目链接 ### 题目大意: 小胖和ZYR要去ESQMS森林采蘑菇. ESQMS森林间有N个小树丛,M条小径,每条小径都是单向的,连接两个小树丛,上面都有一定数量的蘑菇.小胖 ...

  9. SDUT-2140_判断给定图是否存在合法拓扑序列

    数据结构实验之图论十:判断给定图是否存在合法拓扑序列 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给定一个有向图,判 ...

随机推荐

  1. VC++ WIN32 sdk实现按钮自绘详解 之二.

    网上找了很多,可只是给出代码,没有详细解释,不便初学者理解.我就抄回冷饭.把这个再拿出来说说. 实例图片:    首先建立一个标准的Win32 Application 工程.选择a simple Wi ...

  2. 【ASP.NET Web API教程】3.3 通过WPF应用程序调用Web API(C#)

    原文:[ASP.NET Web API教程]3.3 通过WPF应用程序调用Web API(C#) 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本博客文章,请先看前面的 ...

  3. DMP文件的生成和使用

    1.生成dmp的程序 #include  <dbghelp.h> #pragma comment(lib,  "dbghelp.lib") //设置异常处理回调函数Se ...

  4. [Android]获取设备相关信息

    public static int screenWidth(Activity activity) { DisplayMetrics dm = new DisplayMetrics(); activit ...

  5. [Cocos2d-x]代码段记录

    一些零碎的代码,便于以后查找 1.添加动画 //添加动画帧 CCAnimation* animation = CCAnimation::create(); ; i< ;i++) { ] = {} ...

  6. Java基础之数组序列化、反序列化 小发现(不知道 是不是有问题)

    结论:  数组,无论是否声明为transient,都是可以序列化.反序列化的. 测试情况如下: 1.两种类型的数组:int .String: 2 声明为transient  或者不做任何修饰:. 3. ...

  7. Spring MVC Hello World Example(转)

    Spring 3 You may interest at this Spring 3 MVC hello world example. In Spring MVC web application, i ...

  8. docs/pcs/rest/file data apis list - 百度开发者中心

    docs/pcs/rest/file data apis list - 百度开发者中心 更新通知: 2013.6.20 上传.下载新域名正式上线使用,相关接口“上传单个文件”.“分片上传-文件分片上传 ...

  9. BZOJ 2809 APIO2012 dispatching Treap+启示式合并 / 可并堆

    题目大意:给定一棵树,选定一棵子树中的一些点,薪水和不能超过m,求点的数量*子树根节点的领导能力的最大值 考虑对于每一个节点,我们维护一种数据结构,在当中贪心寻找薪金小的雇佣. 每一个节点暴力重建一定 ...

  10. FZU2181+poj2942(点双连通+判奇圈)

    分析:我们对于那些相互不憎恨的人连边,将每次参加会议的所有人(不一定是全部人,只需人数>=3且为奇数)看做一个点双联通分量,那么每个点都至少有两个点与他相邻.即需要保证双联通分量中存在奇圈.至于 ...