反向拓扑排序的两道题目:
两道题的却别在于(给数据,自行体会哈):
1
3 1
3 1
poj3687 ans:2 3 1
hdu4857 ans:3 1 2
我个人觉得hdu4857才是真正的答案。
hdu4857 代码 187ms
/*
题意为拓扑排序,使得小的结点尽可能的排在前面:
如:1->4->2 3->5
应让结点1尽量排在前面,再使2尽量排在前面... ...:1 4 2 3 5
若直接按结点从小到大拓扑排序(字典序),无法得到正解:1 3 4 2 5
反向拓扑排序,先输出大的,就能确保小的位于大的前面
*/
#include <queue>
#include <vector>
#include <cstdio>
#include<string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
vector<int>vec[30010];
int outdegree[30010];
int ans[30010];
int cas,n,m,a,b;
inline void read(int &m)
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
m=x*f;
}
void topsort()
{
priority_queue<int>que;
int id=n;
for(int i=1;i<=n;i++)
if(!outdegree[i])
que.push(i);
while(!que.empty())
{
int v=que.top();
que.pop();
ans[id--]=v;
for(int i=0;i<vec[v].size();i++)
if(--outdegree[vec[v][i]]==0)
que.push(vec[v][i]);
}
for(int i=1;i<n;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
int main()
{
read(cas);
while(cas--)
{
read(n);
read(m);
for(int i=1;i<=n;i++)
vec[i].clear();
while(m--)
{
read(a);
read(b);
vec[b].push_back(a);
outdegree[a]++;
}
topsort();
}
return 0;
}
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <vector>
#include <cstdio>
#include <string>
#include<string.h>
#include <iostream>
#include <algorithm>
#include<functional>
using namespace std;
typedef long long ll;
bool graph[210][210];
int outdegree[210];
int ans[210];
int cas,n,m;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
void topsort()
{
priority_queue<int>que;
for(int i=1;i<=n;i++)
if(!outdegree[i])
que.push(i);
int sum=0,k=0;
while(!que.empty())
{
int v=que.top();
que.pop();
ans[v]=n-k; //区别之处。
k++;
for(int i=1;i<=n;i++)
if(graph[i][v])
if(--outdegree[i]==0)
que.push(i);
}
if(k!=n)
{
printf("-1\n");
return ;
}
for(int i=1;i<n;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
int main()
{
cas=read();
while(cas--)
{
memset(graph,0,sizeof(graph));
memset(outdegree,0,sizeof(outdegree));
n=read();
m=read();
int a,b;
while(m--)
{
a=read();
b=read();
if(graph[a][b]==0)
{
graph[a][b]=1;
outdegree[a]++;
}
}
topsort();
}
return 0;
}