题目大意:

给你一个n,m,表示一个无向图G中有n个点,m条边,m>=n-1,然后保证前n-1条边可以构成一棵生成树,然后问对于每条边应该如何修改权值使得前n-1条边构成的生成树是图的最小生成树。输出每条边修改后的值

解题思路:

首先想了很久都没有思路,然后最后怂了,看了别人的题解才发现这么神奇,这题的正解是KM

观察题目我们发现,对于前n-1条边,我们需要的就是将其改小,对于n-1条边之后的边,我们需要的是将其改大,我们知道,对于一条不在生成树上的边k2<u,v>,它如果不能改变最小生成树的话需要满足树上u->v的路径上的任意一条边k1<i,j>有w‘[k1]<=w'[k2](此处是指修改后的),假设第i条边的变化量为change[i],那么也就是说有w[k1]-change[k1]<=w[k2]+change[k2]   =>  w[k1]-w[k2]<=change[k1]+change[k2]

我们发现如果要变化最小的话就有w[k1]-w[k2]=change[k1]+change[k2]这就是KM的条件啊

仔细观察一下这个式子,是不是很像km的w[i][j]<=gx[i]+gy[j],由于当时我们的KM是我讲的,所以我一下就明白了,那么我们可以把每一条边作为一个节点,前  n-1条边设为x节点,后面的边设为y节点,然后将两边的节点补到相同,x与y如果在原图没有边的话就连0边,如何算作有边呢?

就是对于一条不在生成树上的边k2<u,v>,在生成树上u->v的路径上的任意一条边k1<i,j>,我们就在x[k1]与y[k2]间连一条权值为w[k1]-w[k2]的边。之后直接跑一边KM就行了。。。

AC代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#define MAX(a,b) ((a)>(b)?(a):(b))
#define MIN(a,b) ((a)>(b)?(b):(a))using namespace std;int a[510]={0},b[510]={0},z[501]={0};
int g[510][510]={{0}};
int x[510]={0},y[510]={0};
int w[510][510]={{0}};
int slack[510]={0};
int n,m;
int hashx[510]={0};
int hashy[510]={0};
int father[510]={0};bool find(int k)
{hashx[k]=1;for(int i=1;i<=m;i++){if(hashy[i]==0 && w[k][i]==x[k]+y[i]){hashy[i]=1;if(father[i]==0 || find(father[i])==1){father[i]=k;return true;}}else slack[i]=MIN(slack[i],x[k]+y[i]-w[k][i]);}return false;
}void km()
{for(int i=1;i<=m;i++)for(int j=1;j<=m;j++)x[i]=MAX(w[i][j],x[i]);for(int i=1;i<=m;i++){memset(slack,0x3f3f3f3f,sizeof(slack));for(;;){int d=2e9;memset(hashx,0,sizeof(hashx));memset(hashy,0,sizeof(hashy));if(find(i)==1) break;for(int i=1;i<=m;i++)if(hashy[i]==0)d=MIN(d,slack[i]);for(int i=1;i<=m;i++){if(hashx[i]==1)x[i]-=d;if(hashy[i]==1)y[i]+=d;else slack[i]-=d;}}}return;
}bool dfs(int father,int u,int v,int k)
{if(u==v) return true;for(int i=1;i<=n;i++){if(i==father || g[u][i]==0) continue;if(dfs(u,i,v,k)==1){w[g[u][i]][k]=z[g[u][i]]-z[k];return true;}}return false;
}int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i],&b[i],&z[i]);for(int i=1;i<n;i++)g[a[i]][b[i]]=g[b[i]][a[i]]=i;for(int i=n;i<=m;i++)dfs(0,a[i],b[i],i);km();for(int i=1;i<n;i++) printf("%d\n",z[i]-x[i]);for(int i=n;i<=m;i++) printf("%d\n",z[i]+y[i]);return 0;
}

sgu-206 Roads相关推荐

  1. poj pku图论、网络流入门题总结、汇总

    poj pku图论.网络流入门题总结.汇总 分类: acm图论 2010-08-25 18:49 243人阅读 评论(0) 收藏 举报 网络算法networkgraphconstructioninte ...

  2. POJ 图论分类 + DP(较全 自己又加了点)

    DP -----------动态规划 状态压缩DP 2411 (棋盘规模较大)状态压缩DP+DFS+滚动数组 2664 (棋盘规模较小)直接递推即可(DP) 2506 (棋盘规模较小)直接递推即可(D ...

  3. USACO07DEC道路建设Building Roads(prim算法+堆优化与Kruskal+路径压缩对比)

    目录 primprimprim算法 KruskalKruskalKruskal算法 P2872 [USACO07DEC]道路建设Building Roads 4 1 1 1 3 1 2 3 4 3 1 ...

  4. Codeforces Round #323 (Div. 2) A. Asphalting Roads

    A. Asphalting Roads time limit per test 1 second memory limit per test 256 megabytes input standard ...

  5. hdoj 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列+二分)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1025 View Code 1 #include <iostream> 2 #include&l ...

  6. 数论 - SGU 105 DIV3

    SGU 105-DIV 3 Problem's Link Mean: 定义这样一种数列:1,12,123.. 给出一个n,求这个数列中能被3整除的数的个数. analyse: 这道题可以用分析的方法解 ...

  7. SGU 282 Isomorphism

    题目链接 http://acm.sgu.ru/problem.php?contest=0&problem=282 思路 显然有N!N!个边的置换,枚举边的置换肯定不可行. 因此,我们来考虑点置 ...

  8. 洛谷——P2872 [USACO07DEC]道路建设Building Roads

    P2872 [USACO07DEC]道路建设Building Roads 题目描述 Farmer John had just acquired several new farms! He wants ...

  9. SGU 332 Largest Circle(凸包内接圆半径nlogn)

    题目链接:http://acm.sgu.ru/problem.php?contest=0&problem=332 题意:逆时针给出一个凸包,给凸包的最大内接圆半径. 思路:nlogn的算法: ...

  10. 今日SGU 5.25

    SGU 194 题意:无源汇有上下界的最大流 收获:https://wenku.baidu.com/view/0f3b691c59eef8c75fbfb35c.html #include<bit ...

最新文章

  1. Silverlight Telerik RadGridView动态增删行及行列操作(转载)
  2. java用循环给map里面存值_Java中如何遍历Map对象的4种方法
  3. Run service in specified proxyPort via jettyrun
  4. Content management workbench DMWB
  5. mysql中数据库基础操作
  6. rabbitmq可靠性投递_RabbitMQ可靠性
  7. ReSharper卸载后Visual Studio的快捷键和智能提示消失
  8. wsus3.0手工卸载和安装
  9. HCI实验之问卷设计
  10. 计算机无法同步时间同步,在win10中,为什么电脑时间不能同步?
  11. 台式计算机睡眠快捷键,电脑如何设置快捷方式迅速进入睡眠的状态?
  12. jquery学习笔记
  13. FFmpeg将音频、无音频的视频合并为视频
  14. 基于ThinkPHP的校园网上订餐系统设计与实现
  15. pycharm2017.3.3破解到2099年
  16. 【WPS表格】数据透视表刷新后,保持格式不变
  17. 【QT】QByteArray的使用
  18. 生成Aprilgrid标定板
  19. Ubuntu 18.04 LTS安装后要做的11件事情
  20. 一个立体仓库无线网络故障诊断分析案例

热门文章

  1. 基于yolov4作者最新力作yolov7目标检测模型实现火点烟雾检测
  2. MES精益制造管理系统八大功能
  3. 汽车电子学习笔记—AutoSAR之基础软件层(BSW)
  4. c语言小学生四则运算出题_C语言随机10以内四则运算
  5. 免费jsp空间建站攻略【eatj】【入门】【教程】
  6. 电化学气体传感器的工作原理
  7. 配置并检验 S1 上的 SSH 访问
  8. 欧拉角表示以及万向节死锁
  9. eclipse运行出现an error has occur.see the log file解决办法
  10. Java并发编程:可见性、原子性和有序性问题