题意:给定N个字和M行他们之间的关系,要求输出他们的拓扑排序。此题采用边输入边检测的方式,如果发现环,就结束并输出当前行号;如果读取到当前行时,可以确定拓扑序列就输出,不管后面的输入(可能包含环路);如果到最后还是不能确定拓扑序列,就输出指定的字符串。

拓扑排序:对一个有向无环图(Directed Acyclic Graph简称DAG)G进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若 ∈E(G),则u在线性序列中出现在v之前。

分析:首先,拓扑排序的算法还是挺直观的。简单的拓扑排序算法:先找到任意一个没有入边的顶点,然后是显示该顶点,并将它和它的边一起从图中删除。然后,对图的其余部分应用同样的方法处理。如果找不到没有入边的顶点,说明存在回路。这里的实现过程由于要边输入边检测,所以要注意先一次性读取完输入。还要注意图不是强连通的,以及消去一个顶点后的图不是强连通图的这种情况。做的时候感觉要考虑很多情况,但做完了反而想不起那么多来。呵呵,看代码吧!

import java.util.Scanner;

public class Main {
static int n,m;
static int[][] a; //邻接矩阵
static int [] degree; //每个节点的入度
static boolean[] vis; //记录是否被访问
/**
* 拓扑排序,返回排序的序列,返回1说明存在环路。
* @return
*/
public static String topo(){
String s="";
for(int i=0;i<n && isIsolatedNode(i);i++){
int temp=findInDegreeZero();
if(temp!=-1){
//消去顶点后的图还是强连通就满足要求
if(countZeroDegree()==1)
s+=((char)(temp+65));
vis[temp]=true;
for(int j=0;j<n;j++)
if(a[temp][j]==1)
degree[j]--;
}else{
s="1";
break;
}
}
return s;
}
/**
* 读取入度
*/
public static void readInDegree(){
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(a[i][j]!=0 )
degree[j]++;
}
/**
* 由于采用邻接矩阵,所以要判断节点是否在要排序的N个节点中。利于查找入度为0的节点。
* @param num
* @return
*/
public static boolean isIsolatedNode(int num){
int sum=0;
for(int i=0;i<n;i++)
sum+=(a[num][i]+a[i][num]);
if(sum==0)
return false;
else
return true;
}
/**
* 计算入度为零的节点个数,超过一个则说明该图不是强连通图。
* 由于要优先判断是否存在环路,所以不能如果不是强连通图也要等判断是否存在环路。
* @return
*/
public static int countZeroDegree(){
int sum=0;
for(int i=0;i<n;i++)
if(degree[i]==0 && isIsolatedNode(i) && vis[i]==false){
sum++;
}
return sum;
}
/**
* 找到入度为0的节点,不存在就返回-1(存在环路)
* @return
*/
public static int findInDegreeZero(){
for(int i=0;i<n ;i++)
if(degree[i]==0 && vis[i]==false && isIsolatedNode(i)){
return i;
}
return -1;
} public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(true){
n=sc.nextInt();
m=sc.nextInt();
if(n+m==0)
break;
a=new int[n][n];
String result="";
String[] str=new String[m+1];
for(int i=1; i<=m; i++)
str[i]=sc.next();
int i;
for(i=1; i<=m; i++){
vis=new boolean[n];
degree=new int[n];
a[str[i].charAt(0)-65][str[i].charAt(2)-65]=1;
readInDegree();
int beginZeroDegree=countZeroDegree();
result=topo();
//如果结果字符串长度和N相同,并且图是强连通的就输出序列
if(result.length()==n && beginZeroDegree==1){
System.out.println("Sorted sequence determined after "+i+" relations: "+result+".");
break;
//如果存在环路则输出
}else if(result.equals("1")){
System.out.println("Inconsistency found after "+i+" relations.");
break;
}
}
//不存在环路,到最后还是不能确定序列
if((i-1)==m && result.length()!=n)
System.out.println("Sorted sequence cannot be determined.");
}
}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

拓扑排序 POJ 1094 Sorting It All Out的更多相关文章

  1. 拓扑排序 POJ 1049 Sorting It All Out

    题目传送门 /* 拓扑排序裸题:有三种情况: 1. 输入时发现与之前的矛盾,Inconsistency 2. 拓扑排序后,没有n个点(先判断cnt,即使一些点没有边连通,也应该是n,此时错误是有环): ...

  2. ACM: poj 1094 Sorting It All Out - 拓扑排序

    poj 1094 Sorting It All Out Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%lld & ...

  3. 拓扑排序(Topological Sorting)

    一.什么是拓扑排序 在图论中,拓扑排序(Topological Sorting)是一个有向无环图(DAG, Directed Acyclic Graph)的所有顶点的线性序列.且该序列必须满足下面两个 ...

  4. poj 1094 Sorting It All Out (拓扑排序)

    http://poj.org/problem?id=1094 Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Su ...

  5. POJ 1094 Sorting It All Out(拓扑排序+判环+拓扑路径唯一性确定)

    Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 39602   Accepted: 13 ...

  6. [ACM] POJ 1094 Sorting It All Out (拓扑排序)

    Sorting It All Out Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26801   Accepted: 92 ...

  7. [ACM_模拟] POJ 1094 Sorting It All Out (拓扑排序+Floyd算法 判断关系是否矛盾或统一)

    Description An ascending sorted sequence of distinct values is one in which some form of a less-than ...

  8. POJ 1094 Sorting It All Out (拓扑排序,判断序列是否唯一,图是否有环)

    题意:给出n个字符,m对关系,让你输出三种情况:     1.若到第k行时,能判断出唯一的拓扑序列,则输出:         Sorted sequence determined after k re ...

  9. POJ 1094 Sorting It All Out (拓扑排序) - from lanshui_Yang

    Description An ascending sorted sequence of distinct values is one in which some form of a less-than ...

随机推荐

  1. Netty ByteBuf(图解之 2)| 秒懂

    目录 Netty ByteBuf(图解二):API 图解 源码工程 写在前面 ByteBuf 的四个逻辑部分 ByteBuf 的三个指针 ByteBuf 的三组方法 ByteBuf 的引用计数 Byt ...

  2. 【题解】国家集训队礼物(Lucas定理)

    [国家集训队]礼物(扩展Lucas定理) 传送门可以直接戳标题 172.40.23.20 24 .1 答案就是一个式子: \[ {n\choose \Sigma_{i=1}^m w}\times\pr ...

  3. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之开发游戏界面(二)

    连连看的游戏界面十分简单,大致可以分为两个区域: 游戏主界面区 控制按钮和数据显示区 1.开发界面布局 本程序使用一个RelativeLayout作为整体的界面布局元素,界面布局上面是一个自定义组件, ...

  4. MySQL——存储过程

    核心知识点: 1.什么存储过程?它都有哪些优点? 2.存储过程的语法和参数? 3.存储过程有哪些操作? 4.存储过程常用的控制语句? 一.存储过程概论 SQL语句需要先编译然后执行,而存储过程是一组为 ...

  5. Redis缓存全自动安装shell脚本

    我只是把命令放到shell文件中了,方便安装,代码如下: #!/bin/bash # shell的执行选项: # -n 只读取shell脚本,但不实际执行 # -x 进入跟踪方式,显示所执行的每一条命 ...

  6. 每天一个Linux命令(18)loacte命令

    locate 让使用者可以很快速的搜寻档案系统内是否有指定的档案.     (1)用法:   用法:  Locate  [选项] [参数]     (2)功能: 功能:  在mlocate数据库中搜索 ...

  7. flex TweenLite

    本贴已在 AS天地会转发,大家可以参考:http://bbs.actionscript3.cn/viewthread.php?tid=11090&pid=91142&page=1&am ...

  8. 20165101刘天野 2017-2018-2 《Java程序设计》第2周学习总结

    # 20165101刘天野 2017-2018-2 <Java程序设计>第2周学习总结 教材学习内容总结 基本数据类型 逻辑类型:boolean 整型:byte.short.int.lon ...

  9. mysql 索引技巧

    索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型. 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytabl ...

  10. Monkey for Mac 环境配置

    Monkey for Mac环境配置步骤 java环境配置, 直接去官网找对应jdk就可以了 Android  AdtBundle环境配置 1) 下载地址: http://www.jianshu.co ...