hdu 2647 Reward

本文介绍了一种基于有向图的拓扑排序算法实现方法,并详细解释了如何通过使用vector容器和队列来实现该算法。文章还展示了具体的C++代码实现细节。

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

拓扑排序方法如下:

(1)从有向图中选择一个没有前驱(即入度为0)的顶点并且输出它.

(2)从网中删去该顶点,并且删去从该顶点发出的全部有向边.

(3)重复上述两步,直到剩余的网中不再存在没有前趋的顶点为止.

第一次做拓扑排序,有几点要说明一下:

1.vector是一个容器,可以动态分配内存,存储方式是线性的,他有几个常用的函数:

s[b].push_back(a):把a放到b这一数组后面;

s[b].size():测量在s[b]后面放了几个元素。

2.pair中的make_pair(x,y)可以把两个数据组合成一个,在函数需要返回两个整数的时候也可以用这个函数。

3.注意输出的结果要用长整形。

#include <iostream>
 #include<queue>
 #include<vector>
 #include<stdio.h>
 #include<stdlib.h>
 #include<cstring>
 #define maxn 10005
 using namespace std;
 struct {int id;} point[maxn];//节点在排序中所处位次
 typedef pair<int,int>Pair;
 vector<int>map[maxn]; //记录拓扑排序的方式
 queue<Pair>q;
 int m,n;
 __int64 ans;
 int from[maxn];
 bool topo(){
   int count=0;
   for(int i=1;i<=n;i++){
     if(from[i]==0){
       q.push(make_pair(i,0));
       count++;
     }
   }
   while(!q.empty()){
     int x=q.front().first;
     int y=q.front().second;
     q.pop();
     for(int i=0;i<map[x].size();i++){
       int z=map[x][i];
       point[z].id=max(point[z].id,y+1);
       from[z]--;
       if(from[z]==0){
       q.push(make_pair(z,point[z].id));
       count++;
       }
     }
   }
   ans=0;
   for(int i=1;i<=n;i++)
     ans+=point[i].id;
     if(count==n)return true; //不存在环
     else return false;
 }
 
 int main()
 {
   int a,b;
   while(scanf("%d %d",&n,&m)!=EOF){
       memset(from,0,sizeof(from)); //入度
       for(int i=1;i<=n;i++){
         point[i].id=0;
         map[i].clear(); //注意清除上一次的记录
               }
     for(int i=1;i<=m;i++){
       scanf("%d %d",&a,&b);
       map[b].push_back(a);  //注意不要放反了
       from[a]++;
     }
     if(topo())
       printf("%I64d\n",ans+=888*n);
     else
       printf("-1\n");
 
 
   }
     return 0;
 }


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值