首页 > 代码库 > hdu4857 逃生 bestcoder round1 A
hdu4857 逃生 bestcoder round1 A
题目要求要求在满足约束条件的情况下,使小的序号尽力靠前。
坑点就在这里,小的序号尽量靠前并不是代表字典序,它要求多种情况时,先使1靠前(可能1只能在第2或第3位 那么就要使它在第2位),其次2,3。。而不是在当前情况下,该位最小是哪个就输出哪个
所以直接拓扑排序,或者优先队列都是错的,因为这样都只能保证字典序最小。可以参考代码后面的样例理解
正确做法应该是 反向建图后,用最大值优先的优先队列来拓扑排序,这样能保证在可能的情况下,先选最大的,把最小的留到最后选。
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<queue> const int maxn=30010; using namespace std; vector<int> e[maxn]; int n,m,in[maxn],ans[maxn],cnt; struct cmp { bool operator ()(int &a,int &b){ return a<b;//最大值优先 } }; void topo() { priority_queue<int,vector<int>,cmp> q; for(int i=1;i<=n;i++) if(in[i]==0) q.push(i); int flag=0; int x,i; while(!q.empty()) { x=q.top(); q.pop(); ans[++cnt]=x; for(i=0;i<e[x].size();i++) { in[e[x][i]]--; if(in[e[x][i]]==0) q.push(e[x][i]); } } } int main() { int t,a,b,i; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0;i<=n;i++) e[i].clear(); memset(in,0,sizeof in); while(m--) { scanf("%d%d",&a,&b); e[b].push_back(a); in[a]++; } cnt=0; topo(); printf("%d",ans[cnt]); for(i=cnt-1;i>0;i--) printf(" %d",ans[i]); puts(""); } return 0; } /* 4 2 3 2 4 1应该输出4132 */
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。