拓扑排序
时间复杂度:O(n+m)
因每个结点只需加入队列一次,而每个结点加入队列前需要进行入度数量次的操作,因此时间复杂度为
O(n+m)。
无法排序?:当有 类似 0 → 1 ,且 1 → 0 ,或 1 → 2 , 2 → 3 ,3 → 1 ,的时候,会形成一个环,导致上一个队列中的元素被移走后,没有入度为0的点,导致 while( ! q.empty ( ) ) 终止,cnt < n
核心算法 :
void TopSort()
{
for(int i = 1; i <= n; i++)
{
if(inp[i] == 0) q.push(i); //入读为0的点入列
}
while(!q.empty())
{
fir = q.front();
q.pop();
ans[++cnt] = fir; //cnt计数,遍历点的个数
for(int i=0; i<v[fir].size(); i++)
{
sec = v[fir][i];
inp[sec]--;
if(inp[sec] == 0) q.push(sec); //减去一个入度后,入读为0,就进队
}
}
}
完整代码:
题目:https://vjudge.ppsucxtt.cn/contest/451422#problem/A 密码:HPU0805
#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
int inp[1005], ans[1005];
int x, n, fir, sec, cnt;
vector<int> v[1005];
queue<int> q;
bool bfs()
{
for(int i = 1; i <= n; i++)
{
if(inp[i] == 0) q.push(i);
}
while(!q.empty())
{
fir = q.front();
q.pop();
ans[++cnt] = fir;
for(int i=0; i<v[fir].size(); i++)
{
sec = v[fir][i];
inp[sec]--;
if(inp[sec] == 0) q.push(sec);
}
}
if(cnt == n) return 1;
else return 0;
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
while(~scanf("%d",&x), x)
{
v[i].push_back(x);
inp[x]++;
}
}
if(bfs())
{
printf("%d",ans[1]);
for(int i = 2 ; i <= cnt; i++) printf(" %d",ans[i]);
}
else printf("-1");
puts("");
return 0;
}
层层加一:
题目:https://vjudge.ppsucxtt.cn/contest/451422#problem/F 密码:HPU0805
从后向前,层层加一
#include<iostream>
#include<vector>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
int inp[200005], ans[200005];
int x, n, fir, sec, cnt,m,y,jishu,sum,qsize;
vector<int> v[200005];
void bfs()
{
queue<int> q;
sum=0;
jishu=1;
for(int i = 1; i <= n; i++)
{
if(inp[i] == 0) q.push(i);
}
while(!q.empty())
{
qsize=q.size();
while(qsize--) //while代表一层
{
fir = q.front();
q.pop();
cnt++;
for(int i=0; i<v[fir].size(); i++)
{
sec = v[fir][i];
inp[sec]--;
if(inp[sec] == 0)
{
sum+=jishu;
q.push(sec);
}
}
}
jishu++; //一层过后加一
}
}
int main()
{
while(~scanf("%d %d",&n,&m))
{
memset(v,0,sizeof(v));
memset(ans,0,sizeof(ans));
memset(inp,0,sizeof(inp));
cnt=0;
for(int i = 1; i <= m; i++)
{
scanf("%d %d",&x,&y);
{
v[y].push_back(x);
inp[x]++;
}
}
bfs();
if(cnt != n) printf("-1\n");
else printf("%d\n",888*n+sum);
}
return 0;
}