设为首页 加入收藏

TOP

HDU 1285 确定比赛名次(拓扑排序模板)
2015-07-20 17:59:22 来源: 作者: 【 】 浏览:2
Tags:HDU 1285 确定 比赛 名次 拓扑 排序 模板

题意还是比较容易理解的,关键要看到后面的:合条件的排名可能不是唯一的,此时要求输出时编号小的队伍在前;

思路:这道题就是拓扑排序的经典应用了,用队列做的考虑优先编号小的出队就可以了。

拓扑排序:

拓扑排序是对有向无回路图(DAG)顶点的一种排序,它使得如果存在从u到v的有向路径,那么满足序列中u在v前。 所以我们的算法可以描述为这样一个过程: 1、找到整个图中所有的度为0的点,将这些点压进队列(栈)中 2、从队列(栈)中取出一点,输出,将该点及它的边删除,找到它所指向的点,如果改点是一个原点(删除指向它的点后),则压入队列(栈) 3、重复2过程,直到它为空
注:所谓度为0,即没有子节点,为1则只有一个,为2则有2个。为什么要先让度为0的点出来?因为你在定义的时候,度为0的点,则说明其没有父节点,即没有人排在它的前面!
所以基本AC代码:
#include
  
   
#include
   
     using namespace std; int map[502][502],flag[502],m,n,val[502]; void topsort() { int i, j, k=1; for(i=1; i<=n; i++) //有n个点,所以要找n次 { for(j=1; j<=n; j++) { if(flag[j]==0) //循环寻找度为0的点 { flag[j]--; val[k++]=j; for(int x=1; x<=n; x++) //删除指向该点的边 if(map[j][x]) flag[x]--; //使其度为0 break; } if(j>n) return ; } } } int main() { int i,j; while(cin>>n>>m) { memset(map,0,sizeof(map)); memset(flag,0,sizeof(flag)); //初始化所有的点的度为0 int a,b; for(i=1;i<=m;i++) { cin>>a>>b; if(!map[a][b]) { map[a][b]=1; flag[b]++; //度增加 } } topsort(); for(i=1;i<=n; i++) if(i!=n) cout<
    
     

优先队列优化后的代码:

#include
      
       
#include
       
         #include
        
          #include
         
           #include
          
            using namespace std; const int N=510+10; vector
           
             g[N]; //邻接表 int du[N],val[N]; int n,m; void topsort() { int i; priority_queue
            
             , greater
             
               > q;//定义一个优先队列,并定义编号小的优先出队 for(i=1;i<=n;i++) if(!du[i]) q.push(i); int cnt=1; while(!q.empty()) { int u=q.top(); q.pop(); val[cnt++]=u; for(i=0;i
              
               

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇HDU 2795 Billboard(宣传栏贴公.. 下一篇POJ 2827 Buy Tickets(排队问题..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: