以最低成本在城市中建造街道的算法
Algorithm to build streets in a city with minimum cost?
问题详情:
拉霍夫是EMLand的市长。EMLand由十字路口和街道组成。从每个十字路口到任何其他十字路口只有一条路径。交集用正交点 1...n 表示。一家建筑公司向拉肖夫提供了重建EMLand的所有街道,但拉肖夫可以选择at most k of them to be rebuilt.
建筑公司为每条街道提供了新的长度,这意味着在街道重建后,街道的长度会发生变化。现在,拉霍夫作为市长必须明智地选择,以尽量减少所有交叉路口之间的路径长度总和。帮助拉肖夫!
算法:
符号:旧边长度L
,新长度L'
,边集E
。
-
计数(
C
( 长度将减少的edges(E')
数,即 L' -
如果
C
小于或等于K
则
考虑所有边(E'(,即更新E
中所有此类边的长度 -
还
1 .根据 (L'- L( 按升序
对所有边 (E'( 进行排序 2 .根据 L' 降序
对 (L'-L( 相同的边缘(E'' ⊆ E'( 进行排序 3.在 E 中连接 1st K 边(E''' ⊆ E'( 并更新所有此类边的长度 -
构造边 E 和长度为 L 的图形 G
-
应用任何最短距离算法或 DFS 来查找每对节点的距离黑白。
使用优先级队列和Dijkstra算法实现上述算法。
#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
struct s{
int x;
int y;
int a;
int b;
int c;
};
const int MAX = 100000;
const long long INF = 100000000000000000;
vector< pii > G[MAX];
long long d[MAX];
void dijkstra(long long start) {
int u, v, i, c, w;
priority_queue< pii, vector< pii >, greater< pii > > Q;
for(i=0;i<MAX;i++){
d[i]=INF;
}
Q.push(pii(0, start));
d[start] = 0;
while(!Q.empty()) {
u = Q.top().second; // node
c = Q.top().first; // node cost so far
Q.pop(); // remove the top item.
if(d[u] < c) continue;
for(i = 0; i < G[u].size(); i++) {
v = G[u][i].first; // node
w = G[u][i].second; // edge weight
if(d[v] > d[u] + w) {
d[v] = d[u] + w;
//cout<<d[v];
Q.push(pii(d[v], v));
}
}
}
}
bool func(const s s1,const s s2) { return (s1.c < s2.c); }
bool func2(const s s1,const s s2) { return (s1.b < s2.b); }
int main() {
long long n, e, u, V, w,x,y,a,b,t,i,j,k,res,z=2;
s S;
vector<s> v;
map<pair<int,int>,int> m;
map<pair<int,int>,int>::iterator it;
cin>>t;
while(t--){
cin>>n>>k;
for(i = 1; i <= n; i++) G[i].clear();
v.clear();
m.clear();
for(i=1;i<n;i++){
cin>>x>>y>>a>>b;
if(b<a){
S.x = x;
S.y =y;
S.a=a;
S.b=b;
S.c=b-a;
v.push_back(S);
}
m[make_pair(x,y)]=a;
}
if(v.size()<=k){
for(i=0;i<v.size();i++){
m[make_pair(v[i].x,v[i].y)]=v[i].b;
}
it = m.begin();
for(;it!=m.end();++it){
u = it->first.first;
V = it->first.second;
w = it->second;
G[u].push_back(pii(V, w));
G[V].push_back(pii(u, w));
}
res = 0;
for(i=1;i<=n;i++){
dijkstra(i);
for(j= 1; j <= n; j++) {
if(i == j) continue;
if(d[j] >= INF) ;
else res+=d[j];
}
}
cout<<res/z<<"n";
}
else{
sort(v.begin(),v.end(),func);
for(i=0;i<v.size();i++){
j = i;
while(v[i].c==v[j].c&&j<v.size())j++;
sort(v.begin()+i,v.begin()+j,func2);
i=j;
}
for(i=0;i<k;i++){
m[make_pair(v[i].x,v[i].y)]=v[i].b;
}
it = m.begin();
for(;it!=m.end();++it){
u = it->first.first;
V = it->first.second;
w = it->second;
G[u].push_back(pii(V, w));
G[V].push_back(pii(u, w));
}
res = 0;
for(i=1;i<=n;i++){
dijkstra(i);
for(j= 1; j <= n; j++) {
if(i == j) continue;
if(d[j] >= INF) ;
else res+=d[j];
}
}
cout<<res/z<<"n";
}
}
return 0;
}
It passes only 2 test cases out of 9 test cases .
为什么这个算法不起作用?
或者应该在这个算法中进行哪些修改才能被接受?参考:
拉肖夫,EMLand市长
- 遍历树/图(例如,从任何节点开始的非递归DFS(并计算每条边的使用次数(一侧的节点数*另一侧的节点数(
- 对于每个可能的重建,将增量乘以计数
- 排序
- 利润
请注意,这是一棵树,因此,每条边连接两个连接的组件。
假设我们在两个连接的组件 A 和 B 之间有边连接,其中包含 n 和 m 个交点,因此,通过将边减少 x 个单位,我们将总距离减少 n*m*x
。
A---B---C----E
| |
| |
D---- -----F
看上图,B和C之间的边连接两个连接的组件(A,B,D(和(C,E,F(,减小此边的权重将减少(A,B,D(和(C,E,F(之间的距离
因此,算法是选择 k 条边,它具有最大的n*m*x
(如果x
为正(。
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 基于ELO的团队匹配算法
- C++选择排序算法中的逻辑错误
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- C++A*算法并不总是在路径中具有目标节点
- 排序算法c++
- 构建可组合有向图(扫描仪生成器的汤普森构造算法)
- 算法问题:查找从堆栈中弹出的所有序列
- 下面是排序算法O(n)吗
- KMP算法和LPS表构造的运行时间
- 为什么我的排序算法会更改数组值
- 求最大元素位置的分治算法
- 具有非整数边容量的最大流量的Dinic算法
- 到连接组件算法的问题(递归)
- STL算法函数在多个一维容器上的使用
- 读取最后一行代码算法 - c++ 时出现问题
- 括号更改 O(n) 算法
- std::unordered_map 搜索算法是如何实现的?
- 如何实现高效的算法来计算大型数据集的多个不同值?
- 以最低成本在城市中建造街道的算法