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;
}