poj1094

来源:互联网 发布:淘宝网高腰半身a字裙 编辑:程序博客网 时间:2024/05/23 02:19

使用删边法进行了拓扑排序,而DFS 法则可以直接判断是否有环路,但dfs无法判断是否会有多种拓扑序列,

所以可以用删边法不断地 搜索 。

这里给大家推荐两篇不错的关于拓扑排序博文:http://blog.csdn.net/dm_vincent/article/details/7714519

                                                                                     http://www.cnblogs.com/shanyou/archive/2006/11/16/562861.html

(前几天打了几道dp的题目,有点伤心。。。。)

#include <iostream>using namespace std;const int maxn = 30;int map[maxn][maxn];//图邻接矩阵bool tl[maxn];//可达性矩阵,用于判断是否产生环路bool visited[maxn];//dfs 时判断结点是否访问过int pre[maxn];//各个结点的入度bool topo = true;//是否需要拓扑bool only = false;//拓扑排列是否唯一void dfs(int n)//计算n的 可达性矩阵{tl[n] = true;visited[n] = true;for(int i = 0;i < maxn;i++){if(1==map[n][i] && visited[i]==false)dfs(i);}}void solve(int num,int ques)//结点和询问数量{topo= true;only = false;//邻接矩阵,可达性矩阵初始化memset(map,0,sizeof(map));memset(tl,0,sizeof(tl));memset(pre,0,sizeof(pre));char ch1,ch2,c;int relations = 0;for(int i = 0;i < ques;i++){cin>>ch1>>c>>ch2;int m = ch1 - 'A';int n = ch2 - 'A';map[m][n] = 1;pre[n]++;memset(tl,false,sizeof(tl));memset(visited,false,sizeof(visited));//对n 进行深搜dfs(n);//存在反向边if(true==tl[m]){topo = false;//不需要进行拓扑排列relations = i + 1;break;}//尝试进行拓扑排序,Q 为拓扑排序 序列int Q[maxn];memset(Q,0,sizeof(Q));int tot = 0;//统计ru度数为零的结点,超尾指针!!!!!!!!!!!!!for(int k = 0;k < num;k++)if(0==pre[k])Q[tot++] = k;if(tot==1)//只有一个度数为零的结点{//使用删边法only = true;//有可能产生唯一拓扑排序int count = 0;//统计每次新增 度数为1 的结点数while(tot < num){count = 0;//注意 tot是超尾指针int tmpoint = Q[tot - 1];//使用删边法,计算拓扑序列for(int k = 0;k < num;k++){if(1==map[tmpoint][k]){//count++; 失误pre[k]--;if(0==pre[k]){Q[tot++] = k;count++;}}}//for //若count > 1 则 拓扑序列不唯一,不用继续删边法,同时应该将删除的边恢复  处理下一关系if(count > 1){for(int i = 0;i < num;i++){if(1==map[tmpoint][i])pre[i]++;}only = false;break;}}//whileif(only && tot==num)//产生了唯一拓扑排序{cout<<"Sorted sequence determined after "<<i + 1<<" relations: ";for(int i = 0;i < num;i++)cout<<char('A' + Q[i]);cout<<"."<<endl;//在屏蔽掉后续输入后 ,计算下一样例for(int bi = 0;bi < (ques - i - 1);bi++)cin>>ch1>>c>>ch2;break;}else //没有产生唯一的拓扑排序,那么恢复删除的边{memset(pre,0,sizeof(pre));for(int j = 0;j < num;j++)for(int k = 0;k < num;k++)if(1==map[j][k])pre[k]++;}}//if 只有一个度数为一的节点else//有多个度数唯一的结点则处理下一关系{continue;}}//for,处理下一关系//存在反向边if(!topo){cout<<"Inconsistency found after "<<relations<<" relations."<<endl;for(int i = 0;i < ques -relations;i++)cin>>ch1>>c>>ch2;}else if(!only)cout<<"Sorted sequence cannot be determined."<<endl;}int main(){freopen("in.txt","r",stdin);freopen("out.txt","w",stdout);int nu,qu;while(cin>>nu>>qu){if(nu || qu)solve(nu,qu);elsebreak;}return 0;}


0 0
原创粉丝点击