poj 4084:拓扑排序

来源:互联网 发布:ida远程调试linux 编辑:程序博客网 时间:2024/05/17 22:47

poj 4084:拓扑排序


很好的题目,恶心的算法

描述

给出一个图的结构,输出其拓扑排序序列,要求在同等条件下,编号小的顶点在前。

输入
若干行整数,第一行有2个数,分别为顶点数v和弧数a,接下来有a行,每一行有2个数,分别是该条弧所关联的两个顶点编号。
v<=100, a<=500
输出
若干个空格隔开的顶点构成的序列(用小写字母)。
样例输入
6 81 21 31 43 23 54 56 46 5
样例输出
v1 v3 v2 v6 v4 v5

解题方案

显然这是有向图,然后用了一个个人感觉恶心的算法,个人建了一个倒排表,例如针对上述数据


对于invertlist的下标 i,其对应的元素为一个list,其为 能到达 i+1 的结点集合

例如 i =1 时, 则有 1 -> 2 和 3 -> 2

有这样一个表我们就很方便的检测出哪些结点入度为 0,然后就为拓扑排序解决了做了很好的铺垫


个人代码

#include <iostream>#include <fstream>#include <list>#include <vector>#include <algorithm>using namespace std;typedef pair<int,int> edge;typedef list<int>  *elem;void Topological_sort(vector<elem> &invertList);void read_data(edge* & data,int &v,int &e);void main_solution();vector<elem> invert_list(edge * data,int v,int e);int main(){main_solution();system("pause");return 0;}void read_data(edge* & data,int &v,int &e){ifstream reader;reader.open("data.txt");reader>>v;reader>>e;data = new edge[e];for(int i=0;i<e;i++){reader>>data[i].first;reader>>data[i].second;}reader.close();}void main_solution(){edge* data;int v;int e;read_data( data,v,e );vector<elem> invertList = invert_list( data,v,e );Topological_sort(invertList);}vector<elem> invert_list(edge * data,int v,int e){vector<elem> result;result.resize(v);for(int i =0;i<v;i++){result[i] = new list<int>;}for(int i=0;i<e;i++){result[ data[i].second-1 ]->push_back(data[i].first);}return result ;}void Topological_sort(vector<elem> &invertList){const int v = invertList.size(); bool * flag = new bool[v];for(int i=0;i<v;i++){flag[i] = true;}// 找出 v 个元素for(int i=0;i<v;i++){// 找出一个元素int j;for(j=0;j<v;j++){// 已经找到 Vj+1if( flag[j] && invertList[j]->empty() ){break;}}// 踢出 Vj+1flag[j] = false ;for( int n=0;n<v;n++ ){for(list<int>::iterator it = invertList[n]->begin(); it != invertList[n]->end(); it++){if( *it == j+1 ){invertList[n]->erase(it);break;}}}cout<<"v"<<j+1<<" ";}cout<<endl;}



0 0
原创粉丝点击