5 5 2 1 2 4 5 2 4 3 4 2 3 3 2 0 1 2 1 3
5 3 1 2 4 1 3 2HintCase 1. Erase the edge (2->3),(4->5). And the lexicographically largest topological ordering is (5,3,1,2,4).
直接堆+贪心。
显然下一个选取的是i,
当且仅当i是indegree<=剩余删边数nowk,中编号最大的
因此建一个堆,把indegree<=k的扔进去,推出最大编号,
值得一题的是我没算过复杂度,最后直接过了。。
可能nowk降低,是会把原来堆中的元素T出来,但我未能找出TLE的反例
PS:因为next是系统中已有函数所以不能用,,
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<functional> #include<iostream> #include<cmath> #include<cctype> #include<ctime> #include<queue> using namespace std; #define For(i,n) for(int i=1;i<=n;i++) #define Fork(i,k,n) for(int i=k;i<=n;i++) #define Rep(i,n) for(int i=0;i<n;i++) #define ForD(i,n) for(int i=n;i;i--) #define RepD(i,n) for(int i=n;i>=0;i--) #define Forp(x) for(int p=pre[x];p;p=Next[p]) #define Forpiter(x) for(int &p=iter[x];p;p=Next[p]) #define Lson (x<<1) #define Rson ((x<<1)+1) #define MEM(a) memset(a,0,sizeof(a)); #define MEMI(a) memset(a,127,sizeof(a)); #define MEMi(a) memset(a,128,sizeof(a)); #define INF (2139062143) #define F (100000007) #define MAXN (200000+10) #define MAXM (200000+10) typedef long long ll; ll mul(ll a,ll b){return (a*b)%F;} ll add(ll a,ll b){return (a+b)%F;} ll sub(ll a,ll b){return (a-b+(a-b)/F*F+F)%F;} void upd(ll &a,ll b){a=(a%F+b%F)%F;} priority_queue<int> q; bool b[MAXN]={0}; int indegree[MAXN]={0}; int edge[MAXM],pre[MAXN],Next[MAXM],siz=0; void addedge(int u,int v) { edge[++siz]=v; Next[siz]=pre[u]; pre[u]=siz; } int n,m,k; int main() { // freopen("Sorting.in","r",stdin); while(scanf("%d%d%d",&n,&m,&k)==3) { while(!q.empty()) q.pop(); MEM(b) MEM(indegree) MEM(edge) MEM(pre) MEM(Next) siz=0; For(i,m) { int u,v; scanf("%d%d",&u,&v); addedge(u,v); indegree[v]++; } For(i,n) { if (indegree[i]<=k) b[i]=1,q.push(i); } int nowk=k; int flag=0; while(!q.empty()) { int t; while(1) { t=q.top();q.pop(); if (indegree[t]>nowk) b[t]=0; else break; } nowk-=indegree[t];indegree[t]=0; Forp(t) { int v=edge[p]; indegree[v]--; if (indegree[v]<=nowk&&b[v]==0) b[v]=1,q.push(v); } if (flag) printf(" ");flag++; printf("%d",t); if (flag==n) break; } putchar('\n'); } return 0; }