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

14 篇文章 0 订阅
2 篇文章 0 订阅

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

参考:http://blog.csdn.net/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;
}


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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值