HDU 5195 DZY Loves Topological Sorting(优先队列)

DZY Loves Topological Sorting

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 961    Accepted Submission(s): 283


Problem Description
A topological sort or topological ordering of a directed graph is a linear ordering of its vertices such that for every directed edge  (uv)  from vertex  u  to vertex  v u  comes before  v  in the ordering.
Now, DZY has a directed acyclic graph(DAG). You should find the lexicographically largest topological ordering after erasing at most  k  edges from the graph.
 

Input
The input consists several test cases. ( TestCase5 )
The first line, three integers  n,m,k(1n,m105,0km) .
Each of the next  m  lines has two integers:  u,v(uv,1u,vn) , representing a direct edge (uv) .
 

Output
For each test case, output the lexicographically largest topological ordering.
 

Sample Input
  
  
5 5 2 1 2 4 5 2 4 3 4 2 3 3 2 0 1 2 1 3
 

Sample Output
  
  
5 3 1 2 4 1 3 2
Hint
Case 1. Erase the edge (2->3),(4->5). And the lexicographically largest topological ordering is (5,3,1,2,4).
 

题意: 中文题意

分析:题目要求输出的字典序最大,那么我们优先考虑权值大的点,每次选择最大的点,然后如果要其排序靠前就要把指向它的边删除(前提是其入度小于K),维护此时还可以删除的边数k,然后依次枚举次大的点。直到没有边可以删除。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <deque>
#include <list>
#include <set>
#include<malloc.h>
#include <map>
#include <stack>
#include <queue>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <sstream>
#include <fstream>
#include <limits.h>
#define debug "output for debug\n"
#define pi (acos(-1.0))
#define eps (1e-4)
#define inf 0x3f3f3f3f
#define sqr(x) (x) * (x)
using namespace std;
typedef long long ll;
typedef unsigned long long ULL;
const int Max=100005;
int n,m,k;
vector<int>g[Max];
priority_queue<int>q;
int ans[Max];
int rd[Max];
int vis[Max];
void solve()
{
    for(int i=1; i<=n; i++)
        if(rd[i]<=k)
            q.push(i);
    int cnt=0;
    while(!q.empty())
    {
        int tmp=q.top();
        q.pop();
        if(rd[tmp]<=k&&!vis[tmp])
        {
            vis[tmp]=1;
            k-=rd[tmp];
            ans[cnt++]=tmp;
            for(int i=0; i<g[tmp].size(); i++)
            {
                rd[g[tmp][i]]--;
                if(rd[g[tmp][i]]<=k&&!vis[g[tmp][i]]);
                    q.push(g[tmp][i]);
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d%d",&n,&m,&k))
    {
        int u,v;
        for(int i=0; i<=n; i++)
            g[i].clear();
        memset(vis,0,sizeof vis);
        memset(rd,0,sizeof rd);
        for(int i=0; i<m; i++)
        {
            scanf("%d%d",&u,&v);
            g[u].push_back(v);
            rd[v]++;
        }
        solve();
        for(int i=0; i<n-1; i++)
            printf("%d ",ans[i]);
        printf("%d\n",ans[n-1]);
    }
    return 0;
}

题目链接: 点击打开链接




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值