拓扑排序简单题
来源:互联网 发布:oracle数据库面试题 编辑:程序博客网 时间:2024/05/21 09:44
确定比赛名次
题目传送:HDU - 1285 - 确定比赛名次
思路:拓扑排序
AC代码①(遍历找最小字典序):
#include <map>#include <set>#include <cmath>#include <deque>#include <queue>#include <stack>#include <cstdio>#include <cctype>#include <string>#include <vector>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define LL long long#define INF 0x7fffffffusing namespace std;int n, m;int mp[505][505];int deg[505];void topo_sort() { for(int i = 1; i <= n; i ++) { for(int j = 1; j <= n; j ++) { if(deg[j] == 0) { deg[j] --; if(i != n) cout << j << " "; else cout << j << endl; for(int k = 1; k <= n; k ++) { if(mp[j][k] == 1) { deg[k] --; } } break; } } }}int main() { while(scanf("%d %d", &n, &m) != EOF) { memset(mp, 0, sizeof(mp)); memset(deg, 0, sizeof(deg)); int u, v; for(int i = 0; i < m; i ++) { scanf("%d %d", &u, &v); if(!mp[u][v]) {//注意这里一个队可能赢一个队多场 mp[u][v] = 1; deg[v] ++; } } topo_sort(); } return 0;}
AC代码②(优先队列找最小字典序):
#include <map>#include <set>#include <cmath>#include <deque>#include <queue>#include <stack>#include <cstdio>#include <cctype>#include <string>#include <vector>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define LL long long#define INF 0x7fffffffusing namespace std;int n, m;int deg[505];int mp[505][505];int topo[505];int cnt;void bfs() { priority_queue<int, vector<int>, greater<int> > q;//最小堆,因为默认为最大堆,可以通过greater来设置为最小堆 for(int i = 1; i <= n; i ++) { if(deg[i] == 0) { q.push(i); } } while(!q.empty()) { int t = q.top(); q.pop(); topo[cnt ++] = t; for(int i = 1; i <= n; i ++) { if(mp[t][i]) { deg[i] --; if(deg[i] == 0) q.push(i); mp[t][i] = 0;//删边 } } }}int main() { while(scanf("%d %d", &n, &m) != EOF) { memset(deg, 0, sizeof(deg)); int u, v; for(int i = 0; i < m; i ++) { scanf("%d %d", &u, &v); if(!mp[u][v]) {//注意这里一个队可能赢一个队多场 mp[u][v] = 1; deg[v] ++; } } cnt = 0; bfs(); for(int i = 0; i < cnt - 1; i ++) { printf("%d ", topo[i]); } printf("%d\n", topo[cnt - 1]); } return 0; }
产生冠军
题目传送:HDU - 2094 - 产生冠军
思路:因为只要确定是否产生冠军,根据题意可以得知当且仅当入度为0的只有一个时可以产生冠军,可以用map来映射存储的人的名字
AC代码:
#include <map>#include <set>#include <cmath>#include <deque>#include <queue>#include <stack>#include <cstdio>#include <cctype>#include <string>#include <vector>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define LL long long#define INF 0x7fffffffusing namespace std;map<string, int> mp;int deg[1005];int cnt;int n;int main() { while(scanf("%d", &n) != EOF) { if(n == 0) break; memset(deg, 0, sizeof(deg)); cnt = 1; mp.clear(); string s1, s2; for(int i = 0; i < n; i ++) { cin >> s1 >> s2;// cout << s1 << " " << s2 << endl; if(mp.find(s1) == mp.end()) { mp[s1] = cnt ++; } if(mp.find(s2) == mp.end()) { mp[s2] = cnt ++; } int t1 = mp[s1]; int t2 = mp[s2]; deg[mp[s2]] ++; } int sum = 0; for(int i = 1; i < cnt; i ++) { if(deg[i] == 0) { sum ++; } } if(sum == 1) { printf("Yes\n"); } else printf("No\n"); } return 0;}
Reward
题目传送:HDU - 2647 - Reward
思路:拓扑排序,倒着往前推,即把u->v的边在建图的时候看成v->u。
AC代码:
#include <map>#include <set>#include <cmath>#include <deque>#include <queue>#include <stack>#include <cstdio>#include <cctype>#include <string>#include <vector>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>#define LL long long#define INF 0x7fffffffusing namespace std;const int maxn = 10005;int n, m;int sum, ans;struct node { int x, p; node() {} node(int _x, int _p) : x(_x), p(_p) {}}; vector<int> mp[maxn];int deg[maxn];void topo() { queue<node> que; for(int i = 1; i <=n; i ++) { if(deg[i] == 0) { que.push(node(i, 888)); sum --; ans += 888; } } while(!que.empty()) { node t = que.front(); que.pop(); int d = mp[t.x].size(); for(int i = 0; i < d; i ++) { deg[mp[t.x][i]] --; if(deg[mp[t.x][i]] == 0) { sum --; ans += t.p + 1; que.push(node(mp[t.x][i], t.p + 1)); } } }}int main() { while(scanf("%d %d", &n, &m) != EOF) { memset(deg, 0, sizeof(deg)); for(int i = 1; i <= n; i ++) {//居然忘记初始化WA了,╮(╯▽╰)╭ mp[i].clear(); } int u, v; for(int i = 0; i < m; i ++) { scanf("%d %d", &u, &v); mp[v].push_back(u); deg[u] ++; } sum = n; ans = 0; topo(); if(sum <= 0) { printf("%d\n", ans); } else printf("-1\n"); } return 0;}
0 0
- 拓扑排序简单题
- 简单的拓扑排序
- hdu1285 简单拓扑排序
- POJ1094(简单拓扑排序)
- 简单拓扑排序
- 拓扑排序-简单实现
- 简单拓扑排序的实现
- uva 10305 简单拓扑排序
- 简单的拓扑排序模板
- 拓扑排序简单应用poj2367
- poj 1094 简单拓扑排序
- 拓扑排序的简单实现
- 拓扑排序的简单实现
- poj2367一道利用dfs退栈求拓扑排序的简单题
- 拓扑排序题集
- 拓扑排序题集
- 拓扑排序题集
- 拓扑排序题集
- OPENCV笔记(三)截取部分区域显示
- Android中Activity四种启动模式和taskAffinity属性详解
- Codeforces 551 D. GukiZ and Binary Operations
- [web安全] 其他小众类型输入攻击
- 归并排序 java语言实现
- 拓扑排序简单题
- Coins(多重背包+二进制优化)
- bzoj-3143 游走
- 九度oj 1445
- 黑马程序员——自学java基础第一天
- 【Spring Security】之一:Eclipse搭建Spring Security项目
- AndroidDevTools
- hdu 5329 Question for the Leader 枚举,划分图为k个联通的子图
- 栈的压入、弹出序列