Codeforces Round #536 (Div. 2) - D. Lunar New Year and a Wander(最短路)

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 }

原文地址:https://www.cnblogs.com/npugen/p/10800220.html

时间: 2024-08-01 19:10:02

Codeforces Round #536 (Div. 2) - D. Lunar New Year and a Wander(最短路)的相关文章

Codeforces Round #536 (Div. 2) B. Lunar New Year and Food Ordering

#include <bits/stdc++.h> #define N 300010 #define PII pair<int, int> using namespace std; typedef long long LL; int n, m, a[N], c[N], t, d; LL ans = 0; priority_queue<PII, vector<PII>, greater<PII> > Q; int main(){ scanf(&quo

Codeforces Round #536 (Div. 2)

目录 Codeforces Round #536 (Div. 2) A 题目大意 题解 卡点 C++ Code: B 题目大意 题解 卡点 C++ Code: C 题目大意 题解 卡点 C++ Code: D 题目大意 题解 卡点 C++ Code: E 题目大意 题解 卡点 C++ Code: F 题目大意 题解 卡点 C++ Code: Codeforces Round #536 (Div. 2) A 题目大意 给你一个\(n\times n(n\leqslant500)\)的矩阵,只包含.

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities【最短路】

Codeforces Round #257 div.2 D or 450D Jzzhu and Cities[最短路] 题目链接:点击打开 题目大意: 在一个国家中有n个城市(城市编号1~n),m条公路和k条铁路,编号为1的城市为首都,为了节约,不需要的铁路需要关闭,问在保证首都到其余所有城市的最短路不变的条件下,最多有多少条铁路是不需要的. 解法: 这个题比较麻烦,保证首都到其余城市的最短路不变,要求出最多有多少条铁路是不需要的,那肯定是从最短路的代码上下手了,我们首先考虑dijkstra算法

Codeforces Round #536 (Div. 2) E dp + set

https://codeforces.com/contest/1106/problem/E 题意 一共有k个红包,每个红包在\([s_i,t_i]\)时间可以领取,假如领取了第i个红包,那么在\(d_i\)后才能领取下一个红包,每个红包价值\(w_i\),对方假如有机会领取红包他一定会领取,你有m次阻止对方领取的机会,问对方最少可以拿到多少红包 题解 定义dp[i][j]为前i秒用了j次机会让对方拿到最小价值的红包 \(dp[i][j] - > dp[i+1][j+1]\) 假如使用阻止 \(d

Codeforces Round #428 (Div. 2)

Codeforces Round #428 (Div. 2) A    看懂题目意思就知道做了 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i

Codeforces Round #424 (Div. 2) D. Office Keys(dp)

题目链接:Codeforces Round #424 (Div. 2) D. Office Keys 题意: 在一条轴上有n个人,和m个钥匙,门在s位置. 现在每个人走单位距离需要单位时间. 每个钥匙只能被一个人拿. 求全部的人拿到钥匙并且走到门的最短时间. 题解: 显然没有交叉的情况,因为如果交叉的话可能不是最优解. 然后考虑dp[i][j]表示第i个人拿了第j把钥匙,然后 dp[i][j]=max(val(i,j),min(dp[i-1][i-1~j]))   val(i,j)表示第i个人拿

Codeforces Round #424 (Div. 2) C. Jury Marks(乱搞)

题目链接:Codeforces Round #424 (Div. 2) C. Jury Marks 题意: 给你一个有n个数序列,现在让你确定一个x,使得x通过挨着加这个序列的每一个数能出现所有给出的k个数. 问合法的x有多少个.题目保证这k个数完全不同. 题解: 显然,要将这n个数求一下前缀和,并且排一下序,这样,能出现的数就可以表示为x+a,x+b,x+c了. 这里 x+a,x+b,x+c是递增的.这里我把这个序列叫做A序列 然后对于给出的k个数,我们也排一下序,这里我把它叫做B序列,如果我

[Codeforces] Round #352 (Div. 2)

人生不止眼前的狗血,还有远方的狗带 A题B题一如既往的丝帛题 A题题意:询问按照12345678910111213...的顺序排列下去第n(n<=10^3)个数是多少 题解:打表,输出 1 #include<bits/stdc++.h> 2 using namespace std; 3 int dig[10],A[1005]; 4 int main(){ 5 int aa=0; 6 for(int i=1;;i++){ 7 int x=i,dd=0; 8 while(x)dig[++dd

Codeforces Round #273 (Div. 2)

Codeforces Round #273 (Div. 2) 题目链接 A:签到,仅仅要推断总和是不是5的倍数就可以,注意推断0的情况 B:最大值的情况是每一个集合先放1个,剩下都丢到一个集合去,最小值是尽量平均去分 C:假如3种球从小到大是a, b, c,那么假设(a + b) 2 <= c这个比較明显答案就是a + b了.由于c肯定要剩余了,假设(a + b)2 > c的话,就肯定能构造出最优的(a + b + c) / 3,由于肯定能够先拿a和b去消除c,而且控制a和b成2倍关系或者消除