Problem Description
甘晨煜是一家软件公司的创始人,人称“甘老板”。

经过几年的努力,公司已经准备在纳斯达克上市,甘老板自然也是心情大好。随着中秋节的临近,甘老板决定为员工们每人发个红包。

现在的问题是,每人发多少红包呢?要知道,很多员工提出了自己的要求,比如,胡承轩就提出他的红包应该比麻致远的大!

为了图吉利,甘老板决定为每名员工至少发888的红包,同时,他还希望能满足员工们提出的所有的要求,当然,最后是希望发出红包的总金额最少。

Input
输入包含多组测试数据。
每组数据第一行首先是两个整数n和m,分别表示员工的人数是n,员工们一共提出了m条要求。
接着的m行,每行包含2个整数a和b,表示一条要求:a的红包应该比b的大。

n<=10000
m<=20000
员工编号a和b不等,且都在区间[1,n]内

Output
对于每组测试数据,请输出甘老板总共最少需要发出多少金额的红包。
如果不能满足员工提出的全部的要求,直接输出-1即可。


输入样例

2 1
1 2
2 2
1 2
2 1

输出样例

1777
-1
邻接表存储(无须判重边)
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10,M=888;
int indgr[N],p[N],f[N];
vector<int> v[N];
long long toporder(int n)
{
    int hh=0,tt=-1;
    for(int i=1;i<=n;++i)
    {
        if(!indgr[i])
        p[++tt]=i;
    }
    while(hh<=tt)
    {
        int poi=p[hh],qoi;
        for(int i=0;i<v[poi].size();++i)
        {
            qoi=v[poi][i];
            f[qoi]=max(f[qoi],f[poi]+1);
            if(--indgr[qoi]==0)
            {
                p[++tt]=qoi;
            }
        }
        hh++;
    }
    if(tt<n-1) return -1;//注意tt<n-1而不是<n
    long long ans=0;
    for(int i=1;i<=n;++i)
    ans+=f[i];
    return ans;
}
int main()
{
    int n,m,a,b;
    while(scanf("%d%d",&n,&m)==2)
    {
        for(int i=1;i<=n;++i)
            v[i].clear();
        for(int i=1;i<=n;++i)
        {f[i]=M;indgr[i]=0;p[i]=0;
        }
//注意将f赋值为888
while(m--) { scanf("%d%d",&a,&b); if(!count(v[b].begin(),v[b].end(),a)) { v[b].push_back(a); indgr[a]++; } } printf("%lld\n",toporder(n)); } }
链式前向星存储
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10,E=2*1e4+10;
struct e{
    int to,next;
}edge[E];
int head[E],cnt,in[N],f[N],q[N];
void add_edge(int from,int to)
{
    edge[++cnt].to=to;
    edge[cnt].next=head[from];
    head[from]=cnt;
}
long long toporder(int n)
{
    int hh=0,tt=-1,poi,qoi;
    for(int i=1;i<=n;++i)
    if(!in[i]) q[++tt]=i;
    while(hh<=tt)
    {
        poi=q[hh++];
        for(int i=head[poi];i;i=edge[i].next)
        {
            qoi=edge[i].to;
            f[qoi]=max(f[qoi],f[poi]+1);
            if(--in[qoi]==0)
            q[++tt]=qoi;
        }
    }
    if(tt<n-1) return -1;
    long long ans=0;
    for(int i=1;i<=n;++i)
    ans+=f[i];
    return ans;
}
int main()
{
    int n,m,a,b;
    while(scanf("%d%d",&n,&m)==2)
    {
        cnt=0;
        memset(edge,0,sizeof(edge));
        memset(head,0,sizeof(head));
        memset(in,0,sizeof(in));
        memset(q,0,sizeof(q));
        for(int i=1;i<=n;++i)
        f[i]=888;
        while(m--)
        {
            scanf("%d%d",&a,&b);
            add_edge(b,a);
            in[a]++;
        }
        cout<<toporder(n)<<'\n';
    }
}

 

 
 posted on 2023-01-06 10:04  ruoye123456  阅读(161)  评论(0)    收藏  举报