題目:
分析:
思路很簡單,就是找圖中的環。
題解思路:
反向的拓撲排序
一個圖中,如果沒有入度爲0的點,那麼所有的點都在圖上。
代碼1:超時:提醒自己:圖,不要總是想着用最基本的鄰接的那個二維矩陣:
vector<vector<int> > g;
int A[g.size()][g.size()];//A[i][j] i->j
memset(A,0,sizeof(A));
for(int i=0;i<g.size();i++)
{
for(int j=0;j<g[i].size();j++)
{
A[g[i][j]][i]=1;//箭頭反向。
}
}
vector<int> v;
set<int> s;
while(1)
{
//入度爲0的點,即列上全爲0。
int loca=-1;
for(int i=0;i<g.size();i++)
{
int ok=1;
for(int j=0;j<g.size();j++)
{
if(A[j][i]==1){
ok=0;
break;
}
}
if(ok==0) continue;
//i列全爲0了
if(s.count(i)==1) continue;
//1
s.insert(i);
v.push_back(i);
//出度撤銷
for(int k=0;k<g.size();k++)
A[i][k]=0;
loca=1;
break;
}
if(loca==-1) break;
}
sort(v.begin(),v.end());
return v;
代碼2:尋找上面複雜的原因,每次找到入度爲0的點。優化後,還是超時,哎
vector<vector<int> > g;
queue<int> q;
vector<int> v;
map<int,int> m;
vector<vector<int> > rg(g.size(),vector<int>);
//反向
for(int i=0;i<g.size();i++)
{
for(int j=0;j<g[i].size();j++)
{
g[g[i][j]].push_back(i);
}
//尋找g中出度爲0的點。即g【i】爲空。
if(g.size()==0)
{
q.push(i);
}
}
//尋找g中出度爲0的點。即g【i】爲空。
while(1)
{
if(q.size()==0) break;
int c=q.front();
q.pop();
//安全嗎? 用g
int ok=1;
for(int i=0;i<g[c].size();i++)
{
if(m[g[c][i]]=0) {
ok=0;
break;
}
}
if(ok)
{
m[c]=1;
v.push_back(c);
//加入新的可能的 用rg
for(int i=0;i<rg[c].size();i++)
{
if(m[rg[c][i]]) continue;
queue<int> qq=q;
int cc=1;
while(!qq.empty())
{
if(rg[c][i]==qq.front())
{
cc=0;
break;
}
qq.pop();
}
if(cc) q.push(rg[c][i]);
}
}
}
sort(v.begin(),v.end());
return v;
再看題解,直接用數組記錄了度數:
class Solution {
public:
vector<int> eventualSafeNodes(vector<vector<int>>& g) {
queue<int> q;
vector<int> v;
map<int,int> m;
vector<vector<int> > rg(g.size(),vector<int>());
int A[g.size()];
memset(A,0,sizeof(A));
//反向
for(int i=0;i<g.size();i++)
{
for(int j=0;j<g[i].size();j++)
{
rg[g[i][j]].push_back(i);
}
//尋找g中出度爲0的點。即g【i】爲空。
if(g[i].size()==0)
{
q.push(i);
}
A[i]=g[i].size();
}
//尋找g中出度爲0的點。即g【i】爲空。
cout<<q.size();
while(1)
{
if(q.size()==0) break;
int c=q.front();
q.pop();
v.push_back(c);
for(int i=0;i<rg[c].size();i++)
{
A[rg[c][i]]--;
if(A[rg[c][i]]==0) q.push(rg[c][i]);
}
}
sort(v.begin(),v.end());
return v;
}
};