DAG训练题 奥赛奖金

来源:互联网 发布:linux u盘挂载乱码 编辑:程序博客网 时间:2024/05/01 05:06
【问题描述】  
  在2013年的NOIP复赛中,CQYZ高2015级信息学竞赛班的同学们以超强的实力,力压BS,NK,BZ等学校。学校大老板Mr.lu心情很好,决定给每位学生发奖金。并按每个人竞赛的成绩高低计算他们得到奖金的多少,成绩低的肯定要比成绩高的少,但奖金最少为100元。

  但Mr.lu又是一个很@的人,想发出的奖金尽量的少,这让Mr.He很生气。决定给老板出点难题,不将每个同学的成绩直接给他,而是只告诉他:学生a的成绩比学生b的成绩高。这可难坏了财务室的那几爷子!请你来帮助她们。

  注意:每人得到的奖金必须是整数元。    【输入格式】  
  第一行两个整数N,M,N表示学生总数;以下M行,每行2个整数a,b,表示学生a的竞赛成绩学生b高。注意,输入信息中不会出现a比b高,b比c高,c又比a高的情况。    【输出格式】  
输出一个数表示最少总奖金。    【输入样例】  
8 9
1 3
1 7
2 3
2 4
3 4
4 5
4 6
8 6
7 8    【输出样例】  
812

    【数据范围】  
80%的数据满足n<=1000,m<=2000;
100%的数据满足n<=10000,m<=100000。

根据给出的排序建立DAG图,找到分最低的学生一人100(好少!!!)。

分别找到剩余的中分最低的学生,获得指向他的人多1的奖金。

最后加起来。


#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#define maxn 10005
using namespace std;
int n,m,x,y,ans=0;
int rd[maxn]={0},s[maxn];
vector<int>g[maxn];
vector<int>topo;

void fuck() 

queue<int>q;
for(int i=1;i<=n;i++)
if(rd[i]==0) q.push(i),s[i]=100;//i入度为0,说明没有人比i更低
while(!q.empty())
{
int i=q.front();
q.pop();
for(int j=0;j<g[i].size();j++)
{
int k=g[i][j];
if(rd[k]>0) rd[k]--;
if(rd[k]==0) q.push(k);
s[k]=s[i]+1; //经rd==0的排除,k是i之后分最低的
}
}
for(int i=1;i<=n;i++)
   ans+=s[i];
}


int main()
{
freopen("in.txt","r",stdin);
scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) 
    {
        scanf("%d%d",&x,&y);
        g[y].push_back(x);   //由分低的指向高的
        rd[x]++;
    }
    fuck();
    printf("%d",ans);
}



细心的人会发现没有retrun 0;

1 0
原创粉丝点击