题意:过年发奖金,起始奖金为888.越后者比前者多1元。问一共发了多少奖金。

注意:数据中2 1 表示有两个员工,一组数据。接下来一组数据1 2 表示先给2发奖金,再给1发奖金。也就是1的奖金为889,2的奖金为888.

连接:http://acm.hdu.edu.cn/showproblem.php?pid=2647

View Code
#include <iostream>
using namespace std;
#include <vector>
const int MAX=10000+10;
vector<int >map[MAX];
int used[MAX];
int index[MAX];
int step[MAX];
int j;
int sum;
int ss;
int countzero;
void init()
{
    memset(used,0,sizeof(used));
    memset(index,0,sizeof(index));
    memset(step,0,sizeof(step));
    for(int i=0;i<MAX;i++)//=数组越界了
    {
        map[i].clear();//
    }
    sum=0;
    ss=0;
    countzero=0;//记录找到已经扩展了几个点。
}
void find_zero(int n)//找入度为0的点
{
    j=0;
    for(int i=1;i<=n;i++)
    {
        if(index[i] == 0&&!used[i])
        {
            step[++j]=i;
            countzero++;
            used[i]=1;
        }
    }
    sum+=(888+ss)*j;
    if(j)ss++;
}
void cut(int k)//砍点
{
    for(int i=0;i<map[k].size();i++)
    {
        index[map[k][i]]--;
    }
}
void topology(int n)//拓扑图
{
    for(int i=1;i<=n;i++)
    {
        find_zero(n);
        for(int x=1;x<=j;x++)
        {
            cut(step[x]);
        }
    }
    if(countzero!=n)
    {
        cout<<-1<<endl;
        return ;
    }
    cout<<sum<<endl;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        init();
        int a;
        int b;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            map[b].push_back(a);
            index[a]++;
        }
        topology(n);
    }
    return 0;
}