Problem Codeforces Round #536 (Div. 2) - D. Lunar New Year and a Wander
Time Limit: 3000 mSec
Problem Description
Input
Output
Output a line containing the lexicographically smallest sequence a1,a2,…,an Bob can record.
Sample Input
3 2
1 2
1 3
Sample Output
1 2 3
题解:这一场的D和E都是在经典模型的基础上稍加改动,题目很有质量。根据题意就可以想出第一个最暴力的算法,遍历已经遍历到的点,找其相邻节点中未被遍历到的最小的点,这个正确性肯定是没问题的,但是复杂度是O(n^2),再一想,这些已经遍历到的点肯定是组成了一个联通块,并查集维护一下,每次合并的时候把加入集合的点的相邻节点遍历一下,加入到优先队列中不就行了,这不就是Dijkstra算法的思路么,这里的距离是不在集合中的点到集合的距离,按字典序大小给出距离,加入集合的顺序即为答案,轻松搞定。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define REP(i, n) for (int i = 1; i <= (n); i++) 6 #define sqr(x) ((x) * (x)) 7 8 const int maxn = 100000 + 100; 9 const int maxm = 200000 + 100; 10 const int maxs = 256; 11 12 typedef long long LL; 13 typedef pair<int, int> pii; 14 typedef pair<double, double> pdd; 15 16 const LL unit = 1LL; 17 const int INF = 0x3f3f3f3f; 18 const double eps = 1e-14; 19 const double inf = 1e15; 20 const double pi = acos(-1.0); 21 const int SIZE = 100 + 5; 22 const LL MOD = 1000000007; 23 24 struct Edge 25 { 26 int to, next; 27 } edge[maxm<<1]; 28 29 struct HeapNode 30 { 31 int u; 32 bool operator< (const HeapNode &a)const 33 { 34 return u > a.u; 35 } 36 }; 37 38 int n, m; 39 int head[maxn], tot; 40 int dist[maxn]; 41 vector<int> ans; 42 bool vis[maxn]; 43 44 void init() 45 { 46 memset(head, -1, sizeof(head)); 47 tot = 0; 48 } 49 50 void AddEdge(int u, int v) 51 { 52 edge[tot].to = v; 53 edge[tot].next = head[u]; 54 head[u] = tot++; 55 } 56 57 void Dijkstra() 58 { 59 memset(dist, INF, sizeof(dist)); 60 dist[0] = 0; 61 priority_queue<HeapNode> que; 62 que.push((HeapNode{0})); 63 while(!que.empty()) 64 { 65 HeapNode x = que.top(); 66 int u = x.u; 67 que.pop(); 68 vis[u] = true; 69 ans.push_back(u + 1); 70 for(int i = head[u]; i != -1; i = edge[i].next) 71 { 72 int v = edge[i].to; 73 if(vis[v]) 74 continue; 75 if(dist[v] == INF) 76 { 77 dist[v] = v; 78 que.push((HeapNode){v}); 79 } 80 } 81 } 82 } 83 84 int main() 85 { 86 ios::sync_with_stdio(false); 87 cin.tie(0); 88 //freopen("input.txt", "r", stdin); 89 //freopen("output.txt", "w", stdout); 90 cin >> n >> m; 91 init(); 92 int u, v; 93 for(int i = 0; i < m; i++) 94 { 95 cin >> u >> v; 96 u--, v--; 97 AddEdge(u, v); 98 AddEdge(v, u); 99 } 100 Dijkstra(); 101 for(int i = 0; i < ans.size(); i++) 102 { 103 cout << ans[i] << " "; 104 } 105 return 0; 106 }