题目大意:

给你一个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. java输出gc_GC输出澄清
  2. java里顺序表怎么判断是否满_2、顺序表的实现(java代码)
  3. spark出现task不能序列化错误的解决方法 org.apache.spark.SparkException: Task not serializable
  4. android jenkins 配置NDK环境变量
  5. 项响琴C语言书籍在线浏览,电子琴 c语言程序
  6. java printf与println_浅析Java中print、printf、println的区别
  7. 【线程】——等待集(wait,notify,notifyAll)
  8. x的奇幻之旅 (史蒂夫·斯托加茨 著)
  9. sp根据备份文件来创建DB
  10. java实现微信支付
  11. git push或git pull等其他git命令 出现unable to access ‘https://gitee.com/你的git仓库地址)清除网络代理
  12. C语言知识点思维导图
  13. Chrome 插件 CrxMouse 去除后门优化版
  14. Ubuntu 下安装 Python 解释器
  15. 游戏加加:科学的算法+公平的引擎=最真实的BenchMark
  16. java 解析MP3
  17. [RK3399][Android7.1] 调试笔记 --- Recovery模式下无法挂载/data分区
  18. 服务器kvm切换器维修,服务器数字KVM切换器
  19. idea maven添加子moudle父pom被覆盖
  20. 如何顺利获得美国工作签证

热门文章

  1. 诸葛io+DeepShare技术 轻松掌握渠道效果监测
  2. 酷派D539 APP2SD(扩展内存空间\把应用安装到扩展卡)的方法
  3. 每日一题之Vue数据劫持原理是什么?
  4. java写花束_Java作业 题目:16版.情人节送玫瑰花
  5. 天空之城 10孔口琴
  6. 银行降转账额度 “余额宝”要当心了
  7. 计算机学院心理节活动,计算机学院举办系列心理健康教育活动
  8. 液晶面板价格继续下跌,中国面板企业能否盈利面临考验
  9. 腾讯云服务器地域怎么选?地域可用区选择四大因素
  10. 电磁兼容试验项目之谐波电流试验