• 小测题解


    奖学金

    总间限制:
    1000ms
    内存限制:
    128000kB
    描述

    期末考试终于完了,老班决定召开班委会,内容嘛,则是可爱的奖学金的问题((*^__^*)),她叫来了一些班委,每位班委提出了自己的意见:“我认为同学a的奖学金应该比b多!”老班决定要找出一种奖学金方案,满足各位班委的意见,且同时使得总奖学金数最少。每位同学奖学金最少为100元且都为整数。

    【输入】

        第一行两个整数n(0<=n<=10,000),m(0<=m<=20,000),表示同学总数和班委意见数;

        以下m行,每行2个整数a,b,表示某个班委认为第a号同学奖学金应该比第b号同学高。

    输入
    第一行两个整数n,m,表示同学总数和班委意见数;
    以下m行,每行2个整数a,b,表示某个班委认为第a号同学奖学金应该比第b号同学高。
    输出
    若无法找到合法方案,则输出“impossible”(不含引号);否则输出一个数表示最少总奖学金。
    样例输入
    2 11 2
    样例输出
    201
     
    分析:
    	对于所有给出的限制例如 a的奖学金一定比b的高,则建一条由b到a的有向边
    	如此,只要每一次从入度为零的点进行拓扑排序就可以了;
    	也方便了进行判环的操作
    代码如下
     
     
    #include<cstring>
    #include<cstdio>
    #include<queue>
    using namespace std;
    inline void read(int &x){
    	x=0;char ch;
    	while(ch=getchar(),ch<'!');
    	while(x=10*x+ch-'0',ch=getchar(),ch>'!');
    }
    inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
    inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
    const int maxn = 10000 + 10;
    struct node{
        int num;
        int mon; 
        node ():num(0),mon(100){};  
    }G[maxn];
    struct Edge{
    	int to,next;
    }g[20000 + 10];
    int head[maxn],tot=0;
    void add(int u,int v){
    	g[++tot].to = v;
    	g[tot].next = head[u];
    	head[u] = tot; 
    }
    int cnt=0;
    int q[maxn],l=0,r=0;
    int main(){
    //	freopen("reward.in","r",stdin);
    //	freopen("reward.out","w",stdout);
        int n,m;read(n);read(m);
        bool flag = true;int a,b;
        while(m--){
            read(a),read(b);
            add(b,a);
            G[a].num++;//纪录每一个点的入度 
        }
        for (int i = 1; i <= n; i++){
            if (G[i].num == 0){
                q[r] = i;
    			 ++r;
            }
        }
        int tmp;
        while (l<r){
            tmp = q[l];++l;
            for(int i = head[tmp]; i ; i = g[i].next){
                G[g[i].to].num--;
                if(G[g[i].to].mon <= G[tmp].mon)
                   G[g[i].to].mon = G[tmp].mon + 1;
                if(G[g[i].to].num == 0){//入度为零则不可能再一次被更新了 
                    q[r] = g[i].to ; ++r;
                }
            }
        }
        for (int i = 1; i <= n; i++){
            if (G[i].num != 0){
               flag = false;
               break;//判环 
            }
            cnt += G[i].mon;
        }
        if (!flag) printf("impossible");
        else printf("%d", cnt);
        fclose(stdin);fclose(stdout);return 0;
    }             

    人就像命运下的蝼蚁,谁也无法操控自己的人生.
  • 相关阅读:
    动手学深度学习
    实用机器学习
    双向注意力流模型
    深度学习进阶自然语言处理
    整体二分的升华
    2022百度之星 复赛 T3 最大值
    树的难题 BJOI2017 点分治 单调队列
    CF 818 div2
    2022 CCPC 热身赛
    AOJ 完全背包 数量少体积大价值小版本 dp+贪心
  • 原文地址:https://www.cnblogs.com/Skyminer/p/6435565.html
Copyright © 2020-2023  润新知