网易游戏2016笔试题(三)
算法思路:利用了拓扑排序的思想,预先将输入的测试数据存储在邻接表中,首先遍历入度(即无依赖的编译文件),将其存放入优先队列中(之所以不用栈或者Vector保存是为了保证输出的顺序是按照字典序从小到大排列的);
1.队列不为空,取出队列top元素,加入结果集中,所有依赖该编译文件的文件入度减一,如果减一后入度为0,则将改元素加入优先队列中;
2.队列为空,跳出循环;
3.结果集元素个数小于编译文件个数,说明有循环依赖的,输出ERROR;相等则依次输出结果集;
算法复杂度为O(n+e)
#include <iostream>
#include "vector"
#include "queue"
#include <string>
#include<algorithm>
using namespace std;
struct EdgeNode
{
int ID;
string filename;
EdgeNode *next;
bool operator < (const EdgeNode &a) const
{
return a.filename.compare(filename) >= 0 ? false:true;
}
};
struct VertexNode
{
string filename;
int ID;
int indegree;
EdgeNode *next;
};
void OutPutCompileOrder(vector<VertexNode> adjGraph)
{
int i;
vector<string> res;
priority_queue<EdgeNode, vector<EdgeNode>> array;
for (i = 0; i < adjGraph.size(); i++)
{
if (!adjGraph[i].indegree)
{
EdgeNode temp;
temp.filename = adjGraph[i].filename;
temp.ID = i;
temp.next = NULL;
array.push(temp);
}
}
while (!array.empty())
{
int temp = array.top().ID;
res.push_back(adjGraph[temp].filename);
EdgeNode *p = adjGraph[temp].next;
array.pop();
while (p)
{
adjGraph[p->ID].indegree--;
if (adjGraph[p->ID].indegree == 0)
{
EdgeNode temp;
temp.filename = adjGraph[p->ID].filename;
temp.ID = p->ID;
temp.next = NULL;
array.push(temp);
}
p = p->next;
}
}
if (res.size() < adjGraph.size())
{
cout << "ERROR" << endl;
return;
}
for (i = 0; i < res.size(); i++)
cout << res[i] << endl;
}
int main()
{
int t,n,m;
cin >> t;
for (int i = 0; i < t; i++)
{
cin >> n;
VertexNode initadj;
initadj.next = NULL;
vector<VertexNode> adjGraph(n, initadj);
for (int j = 0; j < n; j++)
{
string filename;
int m;
cin >> filename >> m;
VertexNode adjList;
adjGraph[j].filename = filename;
adjGraph[j].ID = j;
adjGraph[j].indegree = m;
for (int k = 0; k < m; k++)
{
EdgeNode *pNode = new EdgeNode;
EdgeNode *temp;
int ID;
cin >> ID;
pNode->ID = j;
pNode->next = NULL;
cout << pNode << endl;
temp = adjGraph[ID].next;
adjGraph[ID].next = pNode;
pNode->next = temp;
}
}
OutPutCompileOrder(adjGraph);
}
return 0;
}