poj 4084:拓扑排序
很好的题目,恶心的算法
给出一个图的结构,输出其拓扑排序序列,要求在同等条件下,编号小的顶点在前。
v<=100, a<=500
6 8 1 2 1 3 1 4 3 2 3 5 4 5 6 4 6 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+1 if( flag[j] && invertList[j]->empty() ) { break; } } // 踢出 Vj+1 flag[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; }
时间: 2024-10-09 04:28:55