【topoSort拓扑排序】1424. 奖金(简单题目看拓扑排序)

74 篇文章 1 订阅

1424.奖金

Description
由于无敌的凡凡在2005年世界英俊帅气男总决选中胜出,Yali Company总经理Mr.Z心情好,决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。
于是Mr.Z下令召开m方会谈。每位参加会谈的代表提出了自己的意见:“我认为员工a的奖金应该比b高!”Mr.Z决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为100元。

【数据范围】
数据满足n<=10000,m<=20000。

Input
第一行两个整数n,m,表示员工总数和代表数;
以下m行,每行2个整数a,b,表示某个代表认为第a号员工奖金应该比第b号员工高。
Output
若无法找到合法方案,则输出“Poor Xed”;否则输出一个数表示最少总奖金。
Sample Input
Copy sample input to clipboard
2 1
1 2
Sample Output
201
算法中最关键的地方加上了注释,注意看那就好了

#include <vector>
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

const int MAXN = 10000+3; 

vector<int> node[MAXN];
int bonus[MAXN];
int inDegree[MAXN];

int main (){
    memset(inDegree, 0, sizeof (inDegree));
    int n ,m,a,b;
    cin>> n >> m;
    while(m--){
        cin>> a>> b;
        node[b].push_back(a);
        inDegree[a]++;
    }
    queue<int> q;
    for (int i = 1; i <= n; ++i) if (!inDegree[i]) q.push(i);
    int ans = 100*n, sorted = 0;
    while(!q.empty() && sorted <= n){
        int now = q.front(); q.pop();
        ans += bonus[now]; sorted ++;
        for (int i = 0; i < node[now].size(); ++i) {
            inDegree[node[now][i]]--;
            if (inDegree[node[now][i]] == 0) q.push(node[now][i]); // 比它小的所有点都已经排好了
            bonus[node[now][i]] = bonus[now] + 1; 
        }
    }
    if (sorted == n) cout << ans<< endl;
    else cout << "Poor Xed"<< endl; 
}
2018/3/22 更新复习一下。

做一个简单的策略分析

#include <iostream>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int MAXN = 10000 + 10;
int indegree[MAXN]; // 记录i的入度数目,即比他便宜的,却还存在的点数
int bonus[MAXN];
vector<int> node[MAXN]; // 比i大点序列。
// 策略:先处理没有任何更小的点。类似于逐步堆积一个堆。先将最底层建立起来,然后,通过建立起来的最小值来推理出其他的数值。
int main() {
    int n, m, a, b, ans, time, head;
    while (cin >> n >> m) {
        ans = n * 100;
        memset(indegree, 0, sizeof(indegree));
        memset(bonus, 0, sizeof(bonus));
        for (int i = 1; i <= n; ++i) node[i].clear();
        for (int i = 1; i <= m; ++i) {
            cin >> a >> b;
            indegree[a]++;
            node[b].push_back(a);
        }
        queue<int> q; // BFS处理DAG
        for (int i = 1; i <= n; ++i) if (indegree[i] == 0) q.push(i);
        time = 0; // count
        while (!q.empty() && time <= n) {
            head = q.front(); q.pop();
            ans += bonus[head]; time++;
            for (int i = 0; i < node[head].size(); ++i) {
                indegree[node[head][i]] --; 
                if (indegree[node[head][i]] == 0) q.push(node[head][i]);
                else if (indegree[node[head][i]] < 0) time = n + 1;
                bonus[node[head][i]] = bonus[head] + 1;
            }
        }
        if (time == n) cout << ans<< endl;
        else cout << "Poor Xed" << endl;
    }
}

最后,老套路,宣传一波自己的公众号!(求关注哇!)
本人中大一肥宅,欢迎大家关注,请扫下面的二维码(〃’▽’〃)


二维码

如果觉得有帮助的话,可以扫码,赞赏鼓励一下!谢谢!


这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

肥宅_Sean

公众号“肥宅Sean”欢迎关注

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值