hdu6141-多校8&最小树形图&朱刘算法-I am your Father!
来源:互联网 发布:郝斌老师c语言笔记 编辑:程序博客网 时间:2024/05/17 08:43
http://acm.hdu.edu.cn/showproblem.php?pid=6141
比赛的时候根本没看那道题。
学习中。mark一下。
最小树形图 就是有向图的最小生成树。
一般用朱刘算法。
1 加入最小的边。如果存在孤立点,那么肯定不会有最小树形图。break
2 如果有 不包含root的环,对环进行缩点。
3 反复进行,直到没有环。
但这一道题还有不一样的地方,因为要求最大,所以全变成负数。
要 v-1这个点 的父节点尽可能小,所以 v-1的邻接边 全加上他的 父节点,
最后在后面的处理。。
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cstdlib>#include <cmath>#include <ctime>#include <vector>#include <queue>#include <stack>#include <deque>#include <string>#include <map>#include <set>using namespace std;#define INF 0x3f3f3f3f#define LL long long#define fi first#define se second#define mem(a,b) memset((a),(b),sizeof(a))const int MAXV=1000+3;//最大顶点数const int MAXE=10000+3;//最大边数struct Edge{ int u, v; int cost;}edge[MAXE];//边集int V,E;//顶点数,边数int pre[MAXV],id[MAXV],vis[MAXV];int in[MAXV];int zhuliu(int root)//返回最小花费{ int res=0; while(true) { for(int i=0;i<V;++i) in[i]=INF; for(int i=0;i<E;++i) if(edge[i].u!=edge[i].v&&edge[i].cost<in[edge[i].v]) { pre[edge[i].v]=edge[i].u; in[edge[i].v]=edge[i].cost;//在所有点中寻找最小的。标定他的 弧头 } for(int i=0;i<V;++i) if(i!=root&&in[i]==INF) return -1;//不存在最小树形图,因为有一个 孤立的点,怎么连都连不到 int tn=0;//新图结点数 for(int i=0;i<V;++i) { id[i]=-1; vis[i]=-1; } in[root]=0; for(int i=0;i<V;++i) { res+=in[i]; int v=i; while(vis[v]!=i&&id[v]==-1&&v!=root) { vis[v]=i; v=pre[v];// 向后遍历。vis是记录的 那条链的尾 } if(v!=root&&id[v]==-1) { for(int u=pre[v];u!=v;u=pre[u]) id[u]=tn; id[v]=tn++;//求环、id是记录环的标号。缩点操作 } } if(tn==0)//没有有向环 break; for(int i=0;i<V;++i) if(id[i]==-1) id[i]=tn++;// 自环 for(int i=0;i<E;i++) { int v=edge[i].v; edge[i].u=id[edge[i].u]; edge[i].v=id[edge[i].v]; if(edge[i].u!=edge[i].v) edge[i].cost-=in[v]; else swap(edge[i],edge[--E]); } V=tn; root=id[root]; } return res;}int main(){ int T; scanf("%d", &T); while(T--){ scanf("%d%d",&V,&E); for(int i=0;i<E;i++){ scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].cost); edge[i].u--,edge[i].v--; edge[i].cost*=-1000; if(edge[i].v==V-1) edge[i].cost+=edge[i].u; } int ans=zhuliu(0); printf("%d %d\n",(-ans+999)/1000,(-ans+999)/1000*1000+ans+1);//最后加1,因为过程中处理的是 0-v-1的,所以要加1变为原来的、 } return 0;}
阅读全文
0 0
- hdu6141-多校8&最小树形图&朱刘算法-I am your Father!
- HDU 6141 I am your Father!(最小树形图)
- HDU 6141 I am your Father!(最小树形图+权值编码)
- HDU 6141 ( I am your Father! ) (最小树形图+权值编码)
- hdu 6141 I am your Father!(最小树形图+权值编码)
- [HDU 6141] I am your Father
- hdu6141 最大树形图+权值编码
- 最小树形图(刘朱算法)
- 最小树形图 模版--朱刘算法
- 最小树形图(朱-刘算法)
- 最小树形图(朱-刘算法)
- hdu4966 最小树形图 /刘朱算法
- 最小树形图 朱刘算法
- 最小树形图(朱-刘算法)
- 最小树形图 朱刘算法
- 最小树形图(朱刘算法)
- 最小树形图-朱刘算法
- 最小树形图 朱刘算法【转载】
- Hibernate的悲观锁、乐观锁
- 代码详解の使用CountDownLatch解决面试问题:T1和T2线程执行计算,T3线程计算结果的统计
- CodeForces
- C++基本语法,入门及提高(5)
- C++11 lambda 表达式解析
- hdu6141-多校8&最小树形图&朱刘算法-I am your Father!
- IntelliJ 设置全局maven
- 233A. Perfect Permutation
- 邮件服务
- springmvc controller跳转后jsp页面无法加载静态资源css,图片等错误解决方法
- java输入输出代码片段
- Redis面试常见问题
- Linux下diff与patch命令的配合使用
- MapReduce找共同好友