hdu 5695(类拓扑排序+贪心)

本文介绍了一种结合拓扑排序与贪心策略解决特定排列问题的方法。通过建立有向图并使用优先队列,文章详细阐述了解决学生排队问题的具体实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

思路:这道题如果不考虑两位同学两两间相互讨厌,那么直接贪心就可以了,但是增加了两两间相互讨厌,那么可以把它们之间的这种关系建图来模拟。如果a不希望b排在他的前面,则a与b建一条a指向b的有向边。那么这就有点像拓扑排序了(网上说这是拓扑排序,我觉得只能说思路有点像)。然后先把入度为0的放入优先队列(由大到小),因为入度为0说明没有人不喜欢他站在前面,所以直接可以排,但是要满足贪心策略,所以优先队列从小到大,然后放入队列中的节点的儿子节点的入度减一,重复刚才的步骤。

参考:http://blog.youkuaiyun.com/queuelovestack/article/details/51471639

代码:

#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=1e5+50;
vector<int> g[maxn];
int indgree[maxn],u,v,mins;
long long ans;

int t,n,m;
int main(){
	while(scanf("%d",&t)!=EOF){
		for(int cas=1;cas<=t;cas++){
			memset(g,0,sizeof(g));
			memset(indgree,0,sizeof(indgree));
			mins=inf;
			ans=0;
			scanf("%d%d",&n,&m);
			for(int i=1;i<=m;i++){
				scanf("%d%d",&u,&v);
				g[u].push_back(v);
				indgree[v]++;
			}
			priority_queue<int,vector<int> >q;
			for(int i=1;i<=n;i++){
				if(!indgree[i]){
					q.push(i);
				}
			}
			while(!q.empty()){
				int temp=q.top();q.pop();
				mins=min(mins,temp);
				ans+=mins;
				for(int i=0;i<g[temp].size();i++){
					int son=g[temp][i];
					indgree[son]--;
					if(!indgree[son])
					q.push(son);
 				}
			}
			printf("%lld\n",ans);
		} 
	} 
	return 0;
}


总结:对于一些有相互关系的问题,可以想是否可以建图,如果是单向关系,则单向边,双向关系则双向边。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值