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
浙公网安备 33010602011771号