我最近写了几篇TAOCP阅读笔记,大家可以去看看
其实我已近把全书很大一部分(除1.2,1.5,2.3,4,5节,及很多Execrise没写完)
好吧开始今天的写作。
(专有名词之前讲过了 大家可以去我之前的文章)了解
Question(TPS.cpp)
Input(TPS.qus)
第一行是一个数 NodeC,表示节点数
后面?行是两个数j,k,表示j在k前输出(1<j,k<=NodeC)
最后一行是两个0
Output(cout)
第1行:
一串从1到n的数字(无空格),并且对于在输入第2~n行出现的所有j,k,j在k前输出
若无满足的序列,则此行输出“Input Error”
第二行(这行是系统输出)
第一行若是Input Error,返回码为1
不然为0(听不懂?死一边去,就是出了错exit(1)不然return 0;)
Test
IN:
9
9 2
3 7
7 5
5 8
8 6
4 6
1 3
7 4
9 5
2 8
0 0
OUT:
193274586
System Exit With Code 0
第二个例子:
IN:
1
1 1
0 0
OUT:
Input Error
System Exit With Code 1
好了,这次我再讲讲思路
大家可以自己买TAOCP哈。
思考一下,拓扑排序无非就是寻找入度为0的那些Node,既然这样我们就应当把这些入度存下来。
为了方便找到值为0的NODE,我们可以把它存在一个Queue/Stack里
每找到一个无入度的NODE,我们需要遍历它所有的出度一遍,为了节省空间复杂度,同时方便遍历出度,我们可以用邻接表替代邻接矩阵。
对了,动态内存分配和指针这次会大量出现,请坐稳扶好。
code:
#include<iostream>
#include<fstream>
#include<queue>
#include<cstring>
#include<cstdlib>
#define ML 1000
using namespace std;
struct Node{
Node* next;
int v;
};
ifstream fin("TPS.qus");
Node* nds=NULL;//自动分配装逼(内存泄漏,深感不安)
queue<int> zs;
queue<int> LR;
int cnt=0;
int un_print=0;
int main(){
//"Tobological sort"
//T1
//输入
fin>>cnt;
un_print=cnt;
//calloc了解一下
//auto allocate mem
nds=(Node*)calloc(cnt+1,sizeof(Node));//直接访问1~n,免得减一
for(int i=1;i<=cnt;++i){
//calloc 自动将值设为0
nds[i].next=NULL;
}
int j=0;
int k=0;
Node* temp=NULL;
while(true){
//T2
fin>>j>>k;
if(j==0)break;
//T3
++(nds[k].v);
temp=(Node*)malloc(sizeof(Node));
temp->v=k;
temp->next=nds[j].next;
nds[j].next=temp;
}
//T4
for(i=1;i<=cnt;++i){
if(nds[i].v==0){zs.push(i);}
}
while(!zs.empty()){
//T5
LR.push(zs.front());
--un_print;
temp=nds[zs.front()].next;
//T6
while(temp!=NULL){
if((--nds[temp->v].v)==0){
zs.push(temp->v);
}
Node* t2=temp;
temp=temp->next;
free((void*)t2);
}
zs.pop();
}
if(un_print!=0){
cout<<"Input Error"<<endl;
exit(1);
}
while(!LR.empty()){
cout<<LR.front();
LR.pop();
}
cout<<endl;
free(nds);
return 0;
}
好啦,下次继续