首页 > 代码库 > POJ 3687 Labeling Balls(逆向拓扑)
POJ 3687 Labeling Balls(逆向拓扑)
正向每次取最小并不能保证为最优解,反向建边每次取最大可得正解。
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<map> #include<queue> #include<vector> #include<cstring> #include<algorithm> #define rep(i,a,b) for(int i=(a);i<(b);i++) #define rev(i,a,b) for(int i=(a);i>=(b);i--) #define clr(a,x) memset(a,x,sizeof a) #define INF 0x3f3f3f3f typedef long long LL; using namespace std; const int maxn=205; const int maxm=maxn*maxn; int first[maxn],nex[maxm],v[maxm],in[maxn],p[maxn],h[maxn]; int n,m,ecnt; bool topsort(int n) { priority_queue<int>q; memset(h,0,sizeof h); for(int i=1;i<=n;i++) if(!in[i])q.push(i); int cur=0; while(!q.empty()) { int x=q.top();q.pop(); p[x]=n-(cur++); for(int e=first[x];~e;e=nex[e]) { h[v[e]]=max(h[v[e]],h[x]+1); if(--in[v[e]]==0)q.push(v[e]); } } return cur==n; } void add_(int a,int b) { v[ecnt]=b; nex[ecnt]=first[a]; first[a]=ecnt++; } int main() { int t,a,b; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); clr(first,-1);ecnt=0; clr(in,0); for(int i=0;i<m;i++) { scanf("%d%d",&a,&b); add_(b,a),in[a]++; } int ans=topsort(n); if(!ans) { puts("-1"); continue; } for(int i=1;i<=n;i++) printf("%d%c",p[i],i==n?'\n':' '); } return 0; }
POJ 3687 Labeling Balls(逆向拓扑)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。