D149 拓扑排序 U201733 奖金
D149 拓扑排序 U201733 奖金_哔哩哔哩_bilibili
每位员工奖金最少为100元,部分员工之间的奖金数存在大于关系,如果存在合理方案,输出最少总奖金。
思路
点之间的大于关系可以用有向边表示,建图后,如果是有向无环图,则有解;如果是有向有环图,则无解
各点的到起点的距离初值均为 100,边权均为 1
跑拓扑排序,按最长路更新各点到起点的距离,对于从 $u$ 到 $v$ 的边,转移方程为 $d[v]=max(d[v],d[u]+1)$
最后,对各点的 d 值求和即答案

相关板子:
// 拓扑排序 O(n) #include<bits/stdc++.h> using namespace std; const int N=10010; int n,m,cnt; vector<int> e[N]; int rd[N],d[N]; bool topo(){ for(int i=1;i<=n;i++) d[i]=100; //各点初值 queue<int> q; for(int i=1; i<=n; i++) if(!rd[i]) q.push(i); while(!q.empty()){ int u=q.front(); q.pop(); cnt++; //记录点数 for(auto v:e[u]){ d[v]=max(d[v],d[u]+1); //起点到v的最长路 if(--rd[v]==0) q.push(v); //入度为0 则入队 } } return cnt==n; } int main(){ cin>>n>>m; for(int i=1,a,b; i<=m; i++){ cin>>a>>b; e[b].push_back(a); //从b向a连边 rd[a]++; //记录入度 } if(topo()){ //如果拓扑排序成功 int ans=0; for(int i=1; i<=n; i++) ans+=d[i]; cout<<ans; } else puts("Poor Xed"); }
浙公网安备 33010602011771号