http://acm.hdu.edu.cn/showproblem.php?pid=1285
题意:中文题
比较裸的拓扑排序,就是题目中要求编号小的队伍应该在前面,所以用一个优先队列,让小的先出队。。
优先队列从小到大的写法是 priority_queue<int, vector<int>,greater<int> > q;
用vector来存储,这样的话不需要进行判重:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define M 600
int mark[M][M];
int indegree[M];
vector<int> G[M];
int n,m;
int ans[M];
void toposort()
{
priority_queue<int, vector<int>,greater<int> > q;
int j = 0;
for(int i = 1;i <= n;i++)
{
if(!indegree[i])
q.push(i);
}
while(!q.empty())
{
int cur = q.top();
ans[j++] = cur;
q.pop();
for(int i = 0;i < G[cur].size();i++)
{
indegree[G[cur][i]]--;
if(indegree[G[cur][i]]==0)
q.push(G[cur][i]);
}
}
}
int main()
{
while(cin >> n >> m)
{
for(int i = 1;i <= n;i++)
G[i].clear();
memset(mark,0,sizeof(mark));
memset(indegree,0,sizeof(indegree));
for(int i = 0;i < m;i++)
{
int a,b;
cin >> a >> b;
G[a].push_back(b);//用一个vector来存储该点所指向的点,这样的话不需要判重,并不会影响结果。
indegree[b]++;
}
toposort();
cout << ans[0];
for(int i = 1;i < n;i++)
cout << " " <<ans[i];
cout << endl;
}
return 0;
}
如果用一个标记数组来存储两个点之间是否有指向,一定要记得判重:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
#define M 600
int mark[M][M];
int indegree[M];
vector<int> G[M];
int n,m;
int ans[M];
void toposort()
{
priority_queue<int, vector<int>,greater<int> > q;
int j = 0;
for(int i = 1;i <= n;i++)
{
if(!indegree[i])
q.push(i);
}
while(!q.empty())
{
int cur = q.top();
ans[j++] = cur;
q.pop();
for(int i = 1;i <= n;i++)
{
if(mark[cur][i]==1)
{
indegree[i]--;
if(indegree[i]==0)
q.push(i);
}
}
}
}
int main()
{
while(cin >> n >> m)
{
memset(mark,0,sizeof(mark));
memset(indegree,0,sizeof(indegree));
for(int i = 0;i < m;i++)
{
int a,b;
cin >> a >> b;
if(mark[a][b]==1) continue; //判重 如果出现过一样的,应该只留一个
mark[a][b] = 1;
indegree[b]++;
}
toposort();
cout << ans[0];
for(int i = 1;i < n;i++)
cout << " " <<ans[i];
cout << endl;
}
return 0;
}