图结构练习——判断给定图是否存在合法拓扑序列(dfs算法(第一个代码),邻接矩阵(前两个代码),邻接表(第三个代码))
图结构练习——判断给定图是否存在合法拓扑序列
Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里^_^
题目描述
输入
输出
示例输入
1 0
2 2
1 2
2 1
示例输出
YES
NO 网上看到有人的思路很巧妙,忍不住就稍作修改,贴了上来:http://www.cnblogs.com/luyingfeng/archive/2013/07/29/3223090.html第一种思路是直接判断环是否存在的思路,这种思路采用dfs算法,是非常规思路:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int vis[];
int m,n,u,v;
int map[][];
int dfs(int u)//深度优先搜索遍历
{
vis[u]=-;//标记-1,正在访问
for(v=; v<=m; v++)
{
if(map[u][v])//如果v是u的后继元素
{
if(vis[v]<)//如果v元素是正在访问中的状态
return ;//存在自环
//如果存在的不是自环
if(!vis[v]&&!dfs(v))//v元素还没有被访问而且v的后继元素和前面的正在访问的元素构成了回路
return ;
}
}
//若果u的后继结点全部没有形成自回路或者是回路
vis[u]=;//标记1,访问完了,删除此节点
return ;
}
int toposort()
{
for(u=; u<=m; u++)
{
if(!vis[u])//如果u节点还没有访问
{
if(!dfs(u))//如果dfs的返回值是0,强制退出排序函数toposort,表明存在环
return ;
}
}
return ;//如果u从1到m全部遍历完
}
int main()
{
while(~scanf("%d %d",&m,&n)&&(m+n!=))
{
memset(vis,,sizeof(vis));
memset(map,,sizeof(map));
for(int i=; i<=n-; i++)
{
scanf("%d %d",&u,&v);
map[u][v]=;
}
if(toposort())//如果返回值是1,不存在回路,无论是自回路或者是回路
printf("YES\n");
else printf("NO\n");//如果返回值是0
}
return ;
}
常规思路,也是书上的思路,即判断是否存在入度为0的节点,若在循环未结束的时候,就找不到入度为0的节点,则必存在环
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int map[][],count[];
int flag;
int u,v,vis;
int main()
{
int m,n;
while(~scanf("%d %d",&m,&n)&&(n!=||m!=))
{
memset(map,,sizeof(map));
memset(count,,sizeof(count));//每个节点的入度初始为0;
vis=;//标记变量,用于帮助最后输出
for(int i=; i<=n-; i++)
{
scanf("%d %d",&u,&v);
map[u][v]=;
count[v]++;
}
for(int i=; i<=m-; i++)
{
int flag=;
for(u=; u<=m; u++)
{
if(count[u]==)
{
flag=;//只要有入度为0的点就变为1
count[u]--;//删除掉这个节点
for(v=; v<=m; v++)//凡是与该节点有关的所有结点入度去掉1;
{
if(map[u][v])
{
count[v]--;
}
}
break;
}
}
if(flag==)//如果没有入度为0的点,就代表没有拓扑序列
{
vis=;
break;
}
}
if(vis==)
printf("YES\n");
else printf("NO\n");
}
return ;
}
以上两种算法全部采用邻接矩阵的方法,但是采用邻接表的方法更具有一般性,这也是以上两种方法的不足之处。
以下是用邻接表的方法:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct vode
{
int v;
struct vode *next;
};
struct vode *f[];
int count[];
int stack[],top=;
int m,n;
int topsort()
{
int i,sum=;
int flag;
while()
{
flag=;
for(i=;i<=m;i++)
{
if(count[i]==)
{
stack[top++]=i;
sum++;
count[i]--;//删除i节点
struct vode *p;
for(p=f[i];p!=NULL;p=p->next)//把i节点的邻接点的入度都减1
{
int t=p->v;
count[t]--;
}
flag=;
}
if(flag==)break;//如果找到了入度是0的节点,从头开始再找入度是0的节点
}
if(flag==)//循环完了之后再也找不到入度是0的节点,这时候可能会有环,也可能没有环
{
break;
}
}
return sum;
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
int i;
memset(count,,sizeof(count));
for(i=;i<=m;i++)
f[i]=NULL;
for(i=;i<=n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
count[v]++;
struct vode *p;
p=(struct vode *)malloc(sizeof(struct vode));
p->v=v;
p->next=f[u];
f[u]=p;
} int sum=topsort();
if(sum!=m)printf("NO\n");
else printf("YES\n");
/*
通过这个循环可以得到最终每个节点的入度,如果是合法的拓扑序列,最终的结果应当都是-1
for(i=1;i<=m;i++)
printf("%d ",count[i]);
printf("\n");
通过下面这个循环可以得到最终一个拓扑序列(如果合法),这个序列可能只是合法序列当中的一个
for(i=1;i<=m;i++)
printf("%d ",stack[i]);
printf("\n");
*/
}
return ;
}
简化后的代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct vode
{
int v;
struct vode *next;
};
struct vode *f[];
int m,n;
int rudu[];
int stack[],top;
void hs()
{
int i,k=;
while(k=!k)
for(i=;i<=m;i++)
if(rudu[i]==)
{
k=;
rudu[i]--;
stack[top++]=i;
struct vode *p;
for(p=f[i];p!=NULL;p=p->next)
rudu[p->v]--;
break;
}
}
int main()
{
while(scanf("%d%d",&m,&n)!=EOF)
{
memset(f,,sizeof(f));
memset(rudu,,sizeof(rudu));
memset(stack,,sizeof(stack));
top=;
int i;
for(i=;i<=n;i++)
{
int u,v;
scanf("%d%d",&u,&v);
rudu[v]++;
struct vode *p;
p=(struct vode *)malloc(sizeof(struct vode));
p->v=v;
p->next=f[u];
f[u]=p;
}
hs();
/*//下面的循环可以显示出拓扑序列
for(i=0;i<=top-1;i++)
printf("%d ",stack[i]);
printf("\n");
*/
if(top==m)printf("YES\n");
else printf("NO\n");
}
return ;
}
测试数据:
5 4
1 3
2 3
3 4
3 5
输出:
YES
-1 -1 -1 -1 -1
1 2 3 4 5
测试连接:http://wenku.baidu.com/view/bb32ee2e4b73f242336c5f53.html
图结构练习——判断给定图是否存在合法拓扑序列(dfs算法(第一个代码),邻接矩阵(前两个代码),邻接表(第三个代码))的更多相关文章
- SDUT2140图结构练习——判断给定图是否存在合法拓扑序列
拓扑序列的判断方法为不存在有向环,代码实现的话有两种,一种是直接去判断是否存在环,较为难理解一些,另一种的话去判断结点入度,如果存在的入度为0的点大于一个,则该有向图肯定不存在一个确定的拓扑序列 #i ...
- 图结构练习——判断给定图是否存在合法拓扑序列(sdutoj)
#include<stdio.h>#include<string.h>int d[15],map[15][15],vis[15];int main(){ int i,j, ...
- SDUT OJ 数据结构实验之图论十:判断给定图是否存在合法拓扑序列
数据结构实验之图论十:判断给定图是否存在合法拓扑序列 Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Prob ...
- SDUT-2140_判断给定图是否存在合法拓扑序列
数据结构实验之图论十:判断给定图是否存在合法拓扑序列 Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 给定一个有向图,判 ...
- 设计一个算法,採用BFS方式输出图G中从顶点u到v的最短路径(不带权的无向连通图G採用邻接表存储)
思想:图G是不带权的无向连通图.一条边的长度计为1,因此,求带顶点u和顶点v的最短的路径即求顶点u和顶点v的边数最少的顶点序列.利用广度优先遍历算法,从u出发进行广度遍历,类似于从顶点u出发一层一层地 ...
- 拓扑排序 判断给定图是否存在合法拓扑序列 自家oj1393
//拓扑排序判断是否有环 #include<cstdio> #include<algorithm> #include<string.h> #include<m ...
- 数据结构实验之图论十:判断给定图是否存在合法拓扑序列(SDUT 2140)
分析:BFS判断是否有环. #include<bits/stdc++.h> using namespace std; typedef long long ll; int gra[200][ ...
- Theano学习笔记(三)——图结构
图结构(Graph Structures)这是理解Theano该基金会的内部运作. Theano编程的核心是用符号占位符把数学关系表示出来. 图结构的组成部分 如图实现了这段代码: importthe ...
- 第6章 图的学习总结(邻接矩阵&邻接表)
我觉得图这一章的学习内容更有难度,其实图可以说是树结构更为普通的表现形式,它的每个元素都可以与多个元素之间相关联,所以结构比树更复杂,然而越复杂的数据结构在现实中用途就越大了,功能与用途密切联系,所以 ...
随机推荐
- win10与ubantu双系统产生的引导错误问题-----unknown filesystem
在win10和ubantu双系统中开机启动时出现unknown filesystem的解决办法 出现上述问题是引导区出错了. 方法如下: grub rescue>ls grub rescue ...
- 用消息机制解耦Activity跳转
我见过的Activity方式有三种: 1, 默认的,在一个Activity里创建一个Intent,然后startActivity/startActivityForResult: 2, 给被跳转到的Ac ...
- Tomcat部署Web应用的两种方式
WEB工程目录结构 部署方式一:此种方式部署,jsp页面修改后,不能动态更新,需要重新部署才能看到效果.不过可以配置动态更新实现. 部署方式二:此种方式部署,jsp修改后,直接在页面可以看到效果.(因 ...
- python——批量下载图片
前言 批量下载网页上的图片需要三个步骤: 获取网页的URL 获取网页上图片的URL 下载图片 例子 from html.parser import HTMLParser import urllib.r ...
- poj 1220(短除法)
http://poj.org/problem?id=1220 题意:进制转换,把a进制转换为b进制. 如果数据不大的话,那么这个题还是很简单的,但这个题就是数据范围太大,所以这里可以采用短除法来做. ...
- docker进入容器的方式
通过docker创建守护运行(在使用-d参数时)的容器时,容器启动后会进入后台.用户无法看到容器中的信息.某些时候如果需要进入容器进行操作,有多种方法,包括使用docker attach命令.dock ...
- cf592d
题意:给出一个无根树,点数为10^5,所有边的长度为1.给定其中有一些点是受到攻击的. 现在要求一个人选定一个点作为起点,走遍所有的受攻击点(不用再回到起点). 需要的最短距离是多少,选定的起点是哪个 ...
- iOS CLLocationManager 定位
今天写个定位,本来很简单,但是在填写plist时,通过系统提示,只能看到NSLocationUsageDescription项目,根本不提示 (1)NSLocationAlwaysUsageDescr ...
- 8.js模式-状态模式
1. 状态模式 var offLightState = function(light){ this.light = light; } offLightState.prototype.buttonWas ...
- 14. javacript高级程序设计-表单
1. 表单脚本 1.1 基础知识 <from>元素表示表单: l acceptCharset:服务器能处理的字符集 l action:接受请求的URL l elements:表单中所有控件 ...