zoukankan      html  css  js  c++  java
  • 奖金

    【问题描述】
      由于无敌的凡凡在2005年世界英俊帅气男总决选中胜出,Yali Company总经理Mr.Z心情好,决定给每位员工发奖金。公司决定以每个人本年在公司的贡献为标准来计算他们得到奖金的多少。于是Mr.Z下令召开m方会谈。每位参加会谈的代表提出了自己的意见:“我认为员工a的奖金应该比b高!”Mr.Z决定要找出一种奖金方案,满足各位代表的意见,且同时使得总奖金数最少。每位员工奖金最少为100元。
    【输入格式】
      第一行两个整数n,m,表示员工总数和代表数;以下m行,每行2个整数a,b,表示某个代表认为第a号员工奖金应该比第b号员工高。
    【输出格式】
      若无法找到合理方案,则输出“Poor Xed”;否则输出一个数表示最少总奖金。
    【输入样例】
      2 1
      1 2
    【输出样例】
      201
    【数据规模】
      80%的数据满足n<=1000,m<=2000;100%的数据满足n<=10000,m<=20000。
    【算法分析】
      首先构图,若存在条件“a的钱比b多”则从b引一条有向指向a;然后拓扑排序,若无法完成排序则表示问题无解(存在圈);若可以得到完整的拓扑序列,则按序列顺序进行递推:
        设f[i]表示第i个人能拿的最少奖金数;
        首先所有f[i]=100(题目中给定的最小值);
       然后按照拓扑顺序考察每个点i,若存在有向边(j,i),则表示f[i]必须比f[j]大,因此我们令f[i] = Max { f[i] , f[j]+1 }即可;
     递推完成之后所有f[i]的值也就确定了,而答案就等于f[1]+…+f[n]。
      部分大数据需要用差分约束系统这个我实在不会
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<stack>
     5 using namespace std;
     6 struct node
     7 {
     8     int u;
     9     int v;
    10     int next;
    11 }edge[10001];
    12 int head[10001];
    13 int num=1;
    14 int rudu[1001];
    15 stack<int>s;
    16 int money[10001];
    17 int ans=0;
    18 int main()
    19 {
    20     int n,m;
    21     scanf("%d%d",&n,&m);
    22     for(int i=1;i<=n;i++)money[i]=100;
    23     for(int i=1;i<=n;i++)head[i]=-1;
    24     for(int i=1;i<=m;i++)
    25     {
    26         scanf("%d%d",&edge[num].v,&edge[num].u);
    27         edge[num].next=head[edge[num].u];
    28         rudu[edge[num].v]++;
    29         head[edge[num].u]=num++;
    30     }
    31     int tot=0;
    32     for(int i=1;i<=n;i++)
    33     {
    34         if(rudu[i]==0)
    35         {
    36             s.push(i);
    37             tot++;
    38         }
    39     }
    40     
    41     while(s.size()!=0)
    42     {
    43         int p=s.top();
    44         s.pop();
    45         for(int i=head[p];i!=-1;i=edge[i].next)
    46         {
    47             if(money[edge[i].v]<money[edge[i].u]+1)
    48             money[edge[i].v]=money[edge[i].u]+1;
    49             rudu[edge[i].v]--;
    50             if(rudu[edge[i].v]==0)
    51             {
    52                 s.push(edge[i].v);
    53                 tot++;
    54             }
    55         }
    56     }
    57     if(tot!=n)printf("-1");
    58     else 
    59     {
    60         for(int i=1;i<=n;i++)
    61         ans=ans+money[i];
    62         printf("%d",ans);
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    codevs 1576 最长严格上升子序列
    codevs 3415 最小和
    codevs 2102 石子归并 2
    洛谷 P1040 加分二叉树
    BZOJ 3038 上帝造题的七分钟二
    codevs 线段树练习ⅠⅡⅢ
    启动Tomcat提示:指定的服务未安装
    poj 1061 青蛙的约会 (扩展欧几里得模板)
    POJ 3449 Geometric Shapes(判断几个不同图形的相交,线段相交判断)
    HDU 5251 矩形面积(二维凸包旋转卡壳最小矩形覆盖问题) --2015年百度之星程序设计大赛
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/6709839.html
Copyright © 2011-2022 走看看