(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

Catalog

Problem:

 Portal: hdu4126 hdu4756

 原题目描述在最下面。


第一题:

 给定一张n(3000)个点的图,q次询问,每次询问增大一条边的权值后最小生成树的值是多少,求答案期望。

第二题:

 给定一张n(1000)个点的图,某两个点间的边可能不存在,问各种情况最小生成树的最大值。

Solution:

 第一题用的\(kruskal\),第二题用的\(prim\)。貌似\(prim\)算法效率更高,毕竟都是稠密图。

 先求MST,跑一边树形\(dp\),\(dp\)数组记录任意两个路径间不在MST上的最小边权值。

 然后就枚举边求解咯。

\[new\_mst = mst - w + dp[u][v]
\]

AC_Code:

hdu4126

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <ctime>
#include <cmath>
#include <iostream>
#define lson(x) cw[x].l
#define rson(x) cw[x].r
using namespace std;
typedef long long LL;
typedef pair<int, int> pii; const int MXN = 3e3 + 5;
const int MXE = 1e7 + 5;
const int INF = 0x3f3f3f3f; int n, m, tot;
vector<int> son[MXN];
struct lp{
int u, v;
int w;
}edge[MXE];
int fa[MXN], rnk[MXN];
int dis1[MXN][MXN], is[MXN][MXN], ar[MXN][MXN];
void init() {
memset(dis1, 0x3f, sizeof(dis1));
memset(is, 0, sizeof(is));
memset(ar, 0x3f, sizeof(ar));
for(int i = 1; i <= n; ++i) {
fa[i] = i;
rnk[i] = 1;
son[i].clear();
ar[i][i] = dis1[i][i] = 0;
}
}
bool cmp(const lp &a, const lp &b) {
return a.w < b.w;
}
int Fi(int x) {
return fa[x] == x? x: fa[x] = Fi(fa[x]);
}
LL kruskal(int k) {
int CNT = 0;
LL ans = 0;
for(int i = 0; i < k; ++i) {
int x = Fi(edge[i].u), y = Fi(edge[i].v);
if(x == y) continue;
if(rnk[x] > rnk[y]) swap(x, y);
fa[x] = y;
rnk[y] += rnk[x];
++ CNT;
ans += edge[i].w;
son[edge[i].u].push_back(edge[i].v);
son[edge[i].v].push_back(edge[i].u);
is[edge[i].u][edge[i].v] = is[edge[i].v][edge[i].u] = 1;
if(CNT == n-1) break;
}
return ans;
}
int dfs(int u,int ba,int r) {
int len = son[u].size(), mi = INF;
for(int i = 0; i < len; ++i) {
int v = son[u][i];
if(v == ba) continue;
int tmp = dfs(v, u, r);
mi = min(mi, tmp);
dis1[u][v] = dis1[v][u] = min(dis1[v][u], tmp);
}
if(r != ba) mi = min(mi, ar[r][u]);
return mi;
}
void solve() {
init();
for(int i = 0; i < m; ++i) {
scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
edge[i].u ++; edge[i].v ++;
ar[edge[i].u][edge[i].v] = ar[edge[i].v][edge[i].u] = edge[i].w;
}
sort(edge, edge + m, cmp);
int ans = kruskal(m), q;
for(int i = 1; i <= n; ++i) dfs(i, -1, i);
LL sum = 0, tmp;
scanf("%d", &q);
for(int i = 0, u, v, w; i < q; ++i) {
scanf("%d%d%d", &u, &v, &w);
u++; v++;
if(is[u][v]) {
tmp = ans - ar[u][v] + min(dis1[u][v], w);
}else {
tmp = ans;
}
sum += tmp;
}
printf("%.4f\n", sum*1.0/q);
}
int main(int argc, char const *argv[]){
while(~scanf("%d%d", &n, &m)&&(n + m)) solve();
return 0;
}

hdu4756

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <ctime>
#include <cmath>
#include <iostream>
#define lson(x) cw[x].l
#define rson(x) cw[x].r
using namespace std;
typedef long long LL;
typedef pair<int, int> pii; const int MXN = 1e3 + 5;
const int MXE = 1e7 + 5;
const int INF = 0x3f3f3f3f; int n;
double m;
vector<int> son[MXN];
int is[MXN][MXN];
double ar[MXN][MXN], dis1[MXN][MXN], dis[MXN];
int pre[MXN], vis[MXN];
LL x[MXN], y[MXN];
void init() {
memset(is, 0, sizeof(is));
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= n; ++j) ar[i][j] = dis1[i][j] = INF;
son[i].clear();
ar[i][i] = dis1[i][i] = 0;
}
}
double prim() {
double sum = 0;
for(int i = 1; i <= n; ++i) {
dis[i] = ar[1][i];
vis[i] = 1;
pre[i] = 1;
}
vis[1] = -1;
for(int J = 1; J < n; ++J) {
int p = -1;
double mm = INF;
for(int i = 1; i <= n; ++i) {
if(vis[i] != -1 && dis[i] < mm) {
p = i; mm = dis[i];
}
}
if(p == -1) break;
sum += mm;
son[p].push_back(vis[p]);
son[vis[p]].push_back(p);
is[p][vis[p]] = is[vis[p]][p] = 1;
vis[p] = -1;
for(int i = 1; i <= n; ++i) {
if(ar[p][i] < dis[i] && vis[i] != -1) {
dis[i] = ar[p][i];
vis[i] = p;
}
}
}
return sum;
}
double dfs(int u,int ba,int r) {
int len = son[u].size();
double mi = INF;
for(int i = 0; i < len; ++i) {
int v = son[u][i];
if(v == ba) continue;
double tmp = dfs(v, u, r);
mi = min(mi, tmp);
dis1[u][v] = dis1[v][u] = min(dis1[v][u], tmp);
}
if(r != ba) mi = min(mi, ar[r][u]);
return mi;
}
LL two(LL x) {
return x * x;
}
void solve() {
scanf("%d%lf", &n, &m);
init();
for(int i = 1; i <= n; ++i) {
scanf("%lld%lld", &x[i], &y[i]);
}
for(int i = 1; i < n; ++i) {
for(int j = i + 1; j <= n; ++j) {
ar[i][j] = ar[j][i] = sqrt(two(x[i]-x[j])*1.0+two(y[i]-y[j]));
}
}
double tmp = prim(), ans = tmp;
//printf("MST = %.2f\n", tmp);
for(int i = 1; i <= n; ++i) dfs(i, -1, i);
for(int i = 2; i < n; ++i) {
for(int j = i + 1; j <= n; ++j) {
if(is[i][j])ans = max(tmp - ar[i][j] + dis1[i][j], ans);
}
}
if(ans >= INF) printf("%.2f\n", tmp * m);
else printf("%.2f\n", ans * m);
}
int main(int argc, char const *argv[]){
int tim;scanf("%d", &tim);
while(tim--) solve();
return 0;
}

Problem Description:

一:

Our story is about Jebei Noyan(哲别), who was one of the most famous generals in Genghis Khan’s cavalry. Once his led the advance troop to invade a country named Pushtuar. The knights rolled up all the cities in Pushtuar rapidly. As Jebei Noyan’s advance troop did not have enough soldiers, the conquest was temporary and vulnerable and he was waiting for the Genghis Khan’s reinforce. At the meantime, Jebei Noyan needed to set up many guarders on the road of the country in order to guarantee that his troop in each city can send and receive messages safely and promptly through those roads.

There were N cities in Pushtuar and there were bidirectional roads connecting cities. If Jebei set up guarders on a road, it was totally safe to deliver messages between the two cities connected by the road. However setting up guarders on different road took different cost based on the distance, road condition and the residual armed power nearby. Jebei had known the cost of setting up guarders on each road. He wanted to guarantee that each two cities can safely deliver messages either directly or indirectly and the total cost was minimal.

Things will always get a little bit harder. As a sophisticated general, Jebei predicted that there would be one uprising happening in the country sooner or later which might increase the cost (setting up guarders) on exactly ONE road. Nevertheless he did not know which road would be affected, but only got the information of some suspicious road cost changes. We assumed that the probability of each suspicious case was the same. Since that after the uprising happened, the plan of guarder setting should be rearranged to achieve the minimal cost, Jebei Noyan wanted to know the new expected minimal total cost immediately based on current information.

Input

There are no more than 20 test cases in the input.

For each test case, the first line contains two integers N and M (1<=N<=3000, 0<=M<=N×N), demonstrating the number of cities and roads in Pushtuar. Cities are numbered from 0 to N-1. In the each of the following M lines, there are three integers xi, yi and ci(ci<=107), showing that there is a bidirectional road between xi and yi, while the cost of setting up guarders on this road is ci. We guarantee that the graph is connected. The total cost of the graph is less or equal to 109.

The next line contains an integer Q (1<=Q<=10000) representing the number of suspicious road cost changes. In the following Q lines, each line contains three integers Xi, Yi and Ci showing that the cost of road (Xi, Yi) may change to Ci (Ci<=107). We guarantee that the road always exists and Ci is larger than the original cost (we guarantee that there is at most one road connecting two cities directly). Please note that the probability of each suspicious road cost change is the same.

Output

For each test case, output a real number demonstrating the expected minimal total cost. The result should be rounded to 4 digits after decimal point.

Sample Input

3 3
0 1 3
0 2 2
1 2 5
3
0 2 3
1 2 6
0 1 6
0 0

Sample Output

6.0000

Hint
The initial minimal cost is 5 by connecting city 0 to 1 and city 0 to 2. In the first suspicious case, the minimal total cost is increased to 6;
the second case remains 5; the third case is increased to 7. As the result, the expected cost is (5+6+7)/3 = 6.

二:

As we all know, Nanjing is one of the four hottest cities in China. Students in NJUST find it hard to fall asleep during hot summer every year. They will never, however, suffer from that hot this year, which makes them really excited. NJUST’s 60th birthday is approaching, in the meantime, 50 million is spent to install air conditioning among students dormitories. Due to NJUST’s long history, the old circuits are not capable to carry heavy load, so it is necessary to set new high-load wires. To reduce cost, every wire between two dormitory is considered a segment. Now, known about all the location of dormitories and a power plant, and the cost of high-load wire per meter, Tom200 wants to know in advance, under the premise of all dormitories being able to supply electricity, the minimum cost be spent on high-load wires. And this is the minimum strategy. But Tom200 is informed that there are so many wires between two specific dormitories that we cannot set a new high-load wire between these two, otherwise it may have potential risks. The problem is that Tom200 doesn’t know exactly which two dormitories until the setting process is started. So according to the minimum strategy described above, how much cost at most you'll spend?

Input

The first line of the input contains a single integer T(T ≤ 100), the number of test cases.

For each case, the first line contains two integers n(3 ≤ n ≤ 1000), k(1 ≤ k ≤ 100). n represents n-1 dormitories and one power plant, k represents the cost of high-load wire per meter. n lines followed contains two integers x, y(0 ≤ x, y ≤ 10000000), representing the location of dormitory or power plant. Assume no two locations are the same, and no three locations are on a straight line. The first one is always the location of the power plant.

Output

For each case, output the cost, correct to two decimal places.

Sample Input

2

4 2
0 0
1 1
2 0
3 1 4 3
0 0
1 1
1 0
0 1

Sample Output

9.66
9.00

hdu4126_hdu4756_求最小生成树的最佳替换边_Kruskal and Prim的更多相关文章

  1. 全连通图求最小生成树边权之积(邻接矩阵/prim/kruskal)

    Description 大家都知道最小生成树一般求的是构成最小生成树的边的权值之和. 现在请求构成最小生成树的边的权值之积 S,最终结果请输出 (S % 100003). P.S. 点之间的边为无向边 ...

  2. Prim算法和Kruskal算法求最小生成树

    Prim算法 连通分量是指图的一个子图,子图中任意两个顶点之间都是可达的.最小生成树是连通图的一个连通分量,且所有边的权值和最小. 最小生成树中,一个顶点最多与两个顶点邻接:若连通图有n个顶点,则最小 ...

  3. (poj)1679 The Unique MST 求最小生成树是否唯一 (求次小生成树与最小生成树是否一样)

    Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definit ...

  4. HDU-1233 还是畅通工程 (prim 算法求最小生成树)

    prim 算法求最小生成树 还是畅通工程 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  5. prime算法求最小生成树(畅通工程再续)

    连着做了四道畅通工程的题,其实都是一个套路,转化为可以求最小生成树的形式求最小生成树即可 这道题需要注意: 1:因为满足路的长度在10到1000之间才能建路,所以不满足条件的路径长度可以初始化为无穷 ...

  6. Kruskal和Prim算法求最小生成树

    Kruskal算法求最小生成树 测试数据: 5 6 0 1 5 0 2 3 1 2 4 2 4 2 2 3 1 1 4 1 输出: 2 3 1 1 4 1 2 4 2 0 2 3 思路:在保证不产生回 ...

  7. Kruskal求最小生成树

    #include<bits/stdc++.h> using namespace std; ; ; const int inf = 0x3f3f3f3f; ; typedef long lo ...

  8. poj 2349 求最小生成树里面第m长的边

    题目链接:https://vjudge.net/problem/POJ-2349 题意: 题目就是要我们找到一个最小的值D,把图里面所有大于D的边去掉之后剩余的连通分支的数量为S.这个就是找这个图里面 ...

  9. hdu 3405 删掉某点后 求最小生成树

    给出N个点的坐标 边的权值为两点间的距离 删掉其中某点 求最小生成树的权值和 要求这权值最小 因为最多50个点 所以具体是删哪个点 用枚举假如有4个点 就要求4次最小生成树 分别是2 3 4 | 1 ...

随机推荐

  1. springboot集成使用rabbitmq笔记(2.rabbitmq使用)

    使用rabbitmq笔记一 使用rabbitmq笔记二 使用rabbitmq笔记三 1.引入包 <dependencies> <dependency> <groupId& ...

  2. Minimum Snap轨迹规划详解(2)corridor与时间分配

    在上一篇文章中,我们得到的轨迹并不是很好,与路径差别有点大,我们期望规划出的轨迹跟路径大致重合,而且不希望有打结的现象,而且希望轨迹中的速度和加速度不超过最大限幅值.为了解决这些问题有两种思路: 思路 ...

  3. 创建一个apk:按钮-click-文字display,测试apk;安装在真机进行调试的方法

    问题引入: 怎么样在一个app做event事件?例如touch操作,滑动操作,和按键事件(back,home等) 回答1:device.touch(x,y) ---获取device对象,然后touch ...

  4. CentOS7简单安装mplayer和vlc!

    http://pkgs.org/在这个网上搜索下面的包的最新版1. sudo rpm -ivh epel-release-7-0.2.noarch.rpm 2. sudo rpm -Uvh elrep ...

  5. PHP面试 PHP基础知识 七(文件及目录处理)

    文件操作 文件打开函数 fopen()函数 //用来打开一个文件 打开时需要指定打开模式 语法:fopen( filename, mode, include_path, context); filen ...

  6. ApiPost

    模拟POST.Get 请求的工具----APIpost(中文版POSTMAN) 快速生成.一键导出api文档 在线模拟调试,结果实时返回 模拟登录后请求API 支持团队协作 模拟POST.Get 请求 ...

  7. Linux 下tomcat+jdk+mysql安装

    JDK 1.用xftp把 jdk1.8.0_65上传到local下 给他赋予最高权限 1)切换到顶级目录    cd ~ 2)然后切换到上级目录 cd .. 3)切换到local路径下  cd /us ...

  8. jsp2自定义标签开篇

    在JSP2中开发标签库需要以下几个步骤: 1.开发自定义标签处理类: 2.建立一个*.tld文件,每个*.tld文件对应一个标签库,每个标签库可包含多个标签: 3.在JSP文件中使用自定义标签. 第一 ...

  9. 解决Office 2010 每次打开word时出现配置进度框

    来自百度经验 装好Office 2010后,每次打开都会出现配置进度框,很烦人,怎么办呢 确认你的10版Office已激活,激活状态如图(激活工具一般在你下载的安装包里都有) 直接在”开始“运行框里输 ...

  10. vfs_path_lookup

    1: void lookupInode() 2: { 3: struct dentry* root_dentry; 4: struct vfsmount* root_mnt; 5: const cha ...