poj1094
来源:互联网 发布:网络推广服务 编辑:程序博客网 时间:2024/05/28 05:15
一个定义:对一个DAG(无环有向图)进行拓扑排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。通常,这样的线性序列称为满足拓扑次序(Topological Order)的序列,简称拓扑序列。
1.本题顺序:
a.先判有没有环,有环就直接输出不能确定;(有两种情况,一种是,直接判断反向边,肯定就有环了,第二种情况是,生成的拓扑序内含字母个数小于题目中给出的字母的个数)
b.如果没有环,那么就看会不会有多种情况,如果有多种情况就再读下一行;如果全部行读完还是有多种情况,就是确定不了
c.如果最后没有环,也不存在多种情况(即每次取出来入度为零的点只有一个),那么才是答案
2.有答案就先出答案,不管后面的会不会矛盾什么的
3.如果在没有读完所有输入就能出答案,一定要把剩下的行都读完。
一开始没有往拓扑排序上面想,一开始想的是,找有向图的环。当然,方法很多了。
首先,可以采用如上的拓扑排序。
第二,可以采用寻找SCC(Strongly Connected Component,即强连通分量)的方法来寻找,因为SCC的定义是,u->v, v->u,这正好是环的特征。至于强联通分量,可以采用Tarjan再或者是一个DFS就可以解决,貌似这样慢一些~(还不会写)
第三,可以采用改进的DFS,我们可以对DFS稍加变化,来解决这个问题。解决的方法如下:(更不会写了)
图中的一个节点,根据其C[N]的值,有三种状态:
0,此节点没有被访问过
-1,被访问过至少1次,其后代节点正在被访问中
1,其后代节点都被访问过。
按照这样的假设,当按照DFS进行搜索时,碰到一个节点时有三种可能:
1、如果C[V]=0,这是一个新的节点,不做处理
2、如果C[V]=-1,说明是在访问该节点的后代的过程中访问到该节点本身,则图中有环。
3、如果C[V]=1,类似于2的推导,没有环。 在程序中加上一些特殊的处理,即可以找出图中有几个环,并记录每个环的路径
P.s.:图论毕竟是数学,这才是正常的做题的节奏!
#include <stack>
using namespace std;
#define MAXN 27
int graph[MAXN][MAXN], indegree[MAXN], list[MAXN], in[MAXN];
int toposort(int n)
{
memcpy(in, indegree, sizeof(indegree));
stack<int> s;
for (int i = 0; i < n; i++)
{
if (!in[i])//no indegree (that is to say the indegree of current node is zero)
s.push(i);
}
int countt = 0;
bool flag = false;
while (!s.empty())
{
if (s.size()>1)
flag = true;//inconsistency of the separate node, 'cuz there exist multiple ways of toposort.
int temp = s.top();
list[countt++] = temp;
s.pop();
for (int i = 0; i < n; i++)
{
if (graph[temp][i] && --in[i] == 0)//if the graph from temp to i is connected and the indegree is still 0 after minus
//you may assume that first let's find the component of the graph who is connected from temp to i
//then, minus itself by one, check if it's indegree is 0 or not.
s.push(i);
}
}
if (countt != n) return 1;//there are a circle in di-graph.(So-called Inconsistency)
else if (flag) return 2;//there are multiple solutions
return 0;//finally there are solution only.
}
int main()
{
int n, m;
while (cin >> n >> m && (n || m))
{
bool flag = false, flag2 = false;
memset(graph, 0, sizeof(graph));
memset(indegree, 0, sizeof(indegree));
for (int i = 1; i <= m; i++)
{
char a, b, waste;
cin >> a >> waste >> b;
if (!flag && !flag2)
{
if (graph[b - 'A'][a - 'A'] == 1)//reverse edge
{
flag2 = true;
cout << "Inconsistency found after " << i << " relations." << endl;
continue;
}
if (graph[a - 'A'][b - 'A'] == 0)//disconnected
{
graph[a - 'A'][b - 'A'] = 1;
indegree[b - 'A']++;//with one indegree of node b
}
int flag3 = toposort(n);
if (flag3 == 0)
{
cout << "Sorted sequence determined after " << i << " relations: ";
for (int j = 0; j < n; j++)
cout << (char)(list[j] + 'A');
cout << '.' << endl;
flag = true;
}
else if (flag3 == 1)
{
cout << "Inconsistency found after " << i << " relations." << endl;
flag2 = true;
}
}
}
if (!flag && !flag2)
cout << "Sorted sequence cannot be determined." << endl;
}
}
- POJ1094
- poj1094
- poj1094
- poj1094
- poj1094
- poj1094
- poj1094
- poj1094
- poj1094
- poj1094
- poj1094
- poj1094
- POJ1094
- poj1094注意事项
- POJ1094解题报告
- Poj1094拓扑排序总结
- 拓扑排序 poj1094
- poj1094 拓扑排序
- 学习资料
- 【PAT】1020. Tree Traversals (25)
- JBoss 系列四十四:jBPM5示例之 GateWay
- 6.9 singleinstance启动模式 & app不在最近任务列表中显示
- 今天一位同学测试了一下sizeof和strlen的区别
- poj1094
- Lucene入门教程(二)- 理解索引过程的核心类
- linux下安装配置intel的tbb
- 实时错误 '-2147217887 (80040e21)':多步操作产生错误
- Getaddrinfo使用测试
- 6.10 采用绑定服务的方式告诉看门狗临时不受保护的app包名
- 中断子系统1_中断子系统初始化
- AJAX+jQuery+ASP实现实时验证身份证信息是否已存在---人事系统
- Android摸索——高仿微博Tab界面