最短路

发布时间 2023-11-30 20:51:41作者: rw156

1.稠密图用邻接矩阵来存

朴素版dijkstra 算法

acwing 849

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 const int N = 2e5 + 10;
 5 
 6 struct node
 7 {
 8     int l,r;
 9     int v;
10     bool operator<(const node &x) const {
11     if(x.v == v) return x.l < l;
12     return x.v < v;
13     }
14 };
15 priority_queue<node> q;
16 
17 int n;
18 char ch; //字符
19 bool bg[N]; //用来判断字符串数组是否为异性,是为异性就可以入堆
20 int a[N]; 
21 bool is[N]; //标记是否出现过
22 int l[N],r[N]; //表示两个端点的左右元素
23 vector<node> ans;
24 
25 int main()
26 {
27     cin >> n;
28     for (int i = 1; i <= n; i ++ ) cin >> ch,bg[i] = (ch == 'B' ? 1 : 0);
29     for (int i = 1; i <= n; i ++ ) cin >> a[i];
30     for (int i = 1; i <= n; i ++ ) l[i] = i - 1,r[i] = i + 1;
31     
32     is[0] = is[n + 1] = 1;
33     for (int i = 2; i <= n; i ++ ) //如果相邻为异性,丢到堆中,从小到大进行排序
34     if(bg[i] ^ bg[i - 1]) q.push({i - 1,i,abs(a[i - 1] - a[i])});
35     
36     while(!q.empty())
37     { //如果堆顶的元素两个端点之前出现过(已经被标记了),那么没用直接删掉
38         while(!q.empty() && (is[q.top().l] || is[q.top().r])) q.pop(); 
39         if(q.empty()) break; //堆为空直接g;
40         node now = q.top(); //now 为堆顶的三个元素(a[i]元素下标)
41         q.pop(); //删掉并更新堆顶
42         int x = l[now.l],y = r[now.r]; // x为堆顶左端点的左边一个点,y同理
43         l[y] = x,r[x] = y; //让x,y互相相邻
44         if(bg[x] ^ bg[y]) q.push({x,y,abs(a[x] - a[y])}); //x,y互为异性丢到堆里面去
45         ans.push_back(now); //把堆顶的元素丢到 ans里面去
46         is[now.l] = 1,is[now.r] = 1; //标记堆顶两个端点出现过了
47         
48     }
49     cout << ans.size() << endl; //有多少对刚才插入的堆顶元素
50     for (auto i : ans ) cout << i.l << ' ' << i.r << endl; //输出每一组的左右端点
51     return 0;
52 }
Code