原题链接:
E. Minimal Labels
题目大意:
给出无向图
逆向拓扑排序
分析:
拓扑排序标号的一般步骤是从小往大,而从大到小时会出现状况
所以只要反向建边,反向编号即可.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair <int,int> pii;
#define mem(s,t) memset(s,t,sizeof(s))
#define D(v) cout<<#v<<" "<<v<<endl
#define inf 0x3f3f3f3f
#define pb push_back
//#define LOCAL
const int mod=1e9+7;
const int MAXN =1e5+10;
vector<int> a[MAXN];
int vis[MAXN];
priority_queue<int,vector<int> > q;
int ans[MAXN];
int main() {
#ifdef LOCAL
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int n,m,N;
cin>>n>>m;
N=n;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
a[y].pb(x);
vis[x]++;
}
for(int i=1;i<=n;i++){
if(!vis[i]) q.push(i);
}
while(!q.empty()){
int t=q.top();
q.pop();
ans[t]=N--;
for(int i=0;i<a[t].size();i++){
vis[a[t][i]]--;
if(!vis[a[t][i]]) q.push(a[t][i]);
}
}
for(int i=1;i<=n;i++) cout<<ans[i]<<" ";
cout<<endl;
return 0;
}
PS.
正向的拓扑排序(模板):
//拓扑排序 ①
#include <cstdio>
#include <cstring>
#define MAXN 517
int G[MAXN][MAXN];//路径
int in_degree[MAXN];//入度
int ans[MAXN];
int n, m, x, y;
int i, j;
void toposort()
{
for(i = 1; i <= n; i++)
{
for(j = 1; j <= n; j++)
{
if(G[i][j])
{
in_degree[j]++;
}
}
}
for(i = 1; i <= n; i++)//从最小的开始寻找,
{//这样保证了有多个答案时序号小的先输出
int k = 1;
while(in_degree[k] != 0)//寻找入度为零的点
k++;
ans[i] = k;
in_degree[k] = -1;
//更新为-1,后边检测不受影响,相当于删除节点
for(int j = 1; j <= n; j++)
{
if(G[k][j])
in_degree[j]--;//相关联的入度减1
}
}
}
void init()
{
memset(in_degree,0,sizeof(in_degree));
memset(ans,0,sizeof(ans));
memset(G,0,sizeof(G));
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
for(i = 0; i < m; i++)
{
scanf("%d%d",&x,&y);
G[x][y] = 1;
}
toposort();
for(i = 1; i < n; i++)
printf("%d ",ans[i]);
printf("%d\n",ans[n]);
}
return 0;
}
//优先队列+拓扑排序
#include<iostream>
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
bool map[517][517];
int in[517];
priority_queue<int,vector<int>,greater<int> > q;
void topo(int n)
{
for(int i=1;i<=n;i++)
{
if(in[i]==0)
q.push(i);
}
int c=1;
while(!q.empty())
{
int v=q.top();
q.pop();
if(c!=n)
{
cout<<v<<" ";
c++;
}
else
cout<<v<<endl;
for(int i=1;i<=n;i++)
{
if(!map[v][i])
continue;
in[i]--;
if(!in[i])
q.push(i);
}
}
}
int main()
{
int n,m,i,j;
while(cin>>n>>m)
{
int k=0;
memset(map,0,sizeof map);
memset(in,0,sizeof in);
while(m--)
{
cin>>i>>j;
if(map[i][j])
continue;
map[i][j]=1;
in[j]++;
}
topo(n);
}
}