您的位置:首页 > 其它

DAG训练题 奥赛奖金

2016-07-08 16:44 232 查看
【问题描述】 
   在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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: