HDU 2647 Reward (拓扑排序)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2647
题意是给你n点m条有向边,叶子点(出度为0)上的值为888,父亲点为888+1,依次计算... 让你求最小的值,但是中间出现有向环就不行了,输出-1。
拓扑排序队列实现,因为叶子是最小的,所以把边反向就可以求了。
//拓扑队列实现 //就是先把入度为0的先入队,然后每次出队的时候把相邻的点的入度减1,要是入度为0则再入队,不断循环直到队列为空 //时间复杂度为O(N + E) //这题就是把边反向就好了 #include <iostream> #include <cstdio> #include <queue> #include <cstring> #include <vector> using namespace std; const int MAXN = 1e4 + 5; typedef pair <int , int> P; vector <int> G[MAXN]; int du[MAXN]; int main() { int n , m , u , v; while(~scanf("%d %d" , &n , &m)) { for(int i = 1 ; i <= n ; i++) { G[i].clear(); du[i] = 0; } for(int i = 0 ; i < m ; i++) { scanf("%d %d" , &u , &v); G[v].push_back(u); du[u]++; } queue <P> que; while(!que.empty()) { que.pop(); } int cont = 0 , res = 0; for(int i = 1 ; i <= n ; i++) { if(!du[i]) { que.push(P(i , 888)); res += 888; cont++; } } while(!que.empty()) { P temp = que.front(); que.pop(); for(int i = 0 ; i < G[temp.first].size() ; i++) { du[G[temp.first][i]]--; if(!du[G[temp.first][i]]) { que.push(P(G[temp.first][i] , temp.second + 1)); res += temp.second + 1; cont++; } } } if(cont == n) { cout << res << endl; } else { cout << -1 << endl; } } }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 继承的思维:从思维模式到架构设计的深度解析
· 如何在 .NET 中 使用 ANTLR4
· 后端思维之高并发处理方案
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· 当职场成战场:降职、阴谋与一场硬碰硬的抗争
· 用99元买的服务器搭一套CI/CD系统
· 35岁程序员的中年求职记:四次碰壁后的深度反思
· Excel百万数据如何快速导入?
· ShadowSql之.net sql拼写神器