有这样一道编程面试题,给一个有向图的邻接矩阵,判别它是否有环。
题目麻烦在给的邻接矩阵是以 ‘字符输入流’ 的形式给出的,所以将其处理成数字形式的是首先要做的工作。
得到邻接矩阵之后,进行拓扑排序即可。假如能完成拓扑排序那就无环,如果不能,那就是有环。
样例输入:
[[0, 1, 0], [0, 0, 1], [1, 0, 0]]
[[0, 0, 0, 1, 0], [1, 0, 0, 0, 0], [0, 0, 0, 1, 1], [0, 0, 0, 0, 0], [0, 1, 0, 0, 0]]
输出:(1代表有环,0代表无环)
1
0
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int str2int(string str){ 5 for(int i=0; i<str.size(); i++){ 6 if(str[i]=='0') return 0; 7 if(str[i]=='1') return 1; 8 } 9 return -1; 10 } 11 12 int main(int argc, char const *argv[]){ 13 string str; 14 while(getline(cin, str) ){ 15 istringstream temp(str); 16 str.clear(); 17 18 string cur; 19 vector<string> data; 20 while(temp>>cur ){ 21 data.push_back(cur ); 22 cur.clear(); 23 } 24 25 int n = sqrt( data.size() ); //n是节点个数 26 vector<vector<int> > graph(n,vector<int>(n,0)); //邻接矩阵 27 28 for(int i=0; i<n; i++){ 29 for(int j=0; j<n; j++){ 30 graph[i][j] = str2int(data[n*i+j]); 31 } 32 } 33 34 vector<int> visited(n,0); //n是节点个数,从上面处理后得到 35 vector<int> indegree(n,0); //各个节点的入度 36 for(int i=0;i<n;i++){ 37 for(int j=0;j<n;j++){ 38 if(graph[i][j]==1){ 39 indegree[j]++; 40 } 41 } 42 } 43 queue<int> q; 44 for(int i=0;i<n;i++){ 45 if(indegree[i]==0) 46 q.push(i); 47 } 48 49 int now; 50 while(!q.empty()){ 51 now = q.front(); 52 q.pop(); 53 visited[now] = 1; 54 for(int i=0;i<n;i++){ 55 if(!visited[i] && graph[now][i]==1){ 56 indegree[i]--; 57 if(indegree[i]==0) q.push(i); 58 } 59 } 60 } 61 62 bool sign = 0; 63 for(int i=0; i<n; i++){ 64 if(!visited[i]){ 65 sign = 1; 66 break; 67 } 68 } 69 70 cout<<sign<<endl; 71 } 72 73 74 return 0; 75 }