最小树形图模板 UVA11183
题意:给定n个节点m条边的有向带权图,求以0为根节点的最小树形图权值大小
用这个代码的时候要注意,这里的数据是从0开始的,边也是从0开始算,
所以在打主代码的时候,如果是从1开始,那么算法里面的从0开始的位置也要相应修改。
特别是下面的 node_circle;
#include<cstdio>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=1e3+;
const int maxm=4e4+;
const int inf=0x3f3f3f3f;
int n,m;
int cost[maxn],pre[maxn],vis[maxn],id[maxn];
struct node
{
int u,v,w;
}a[maxm];
int zhu_liu(int root)
{
int ans=;
while(){
for(int i=;i<n;i++) cost[i]=inf; for(int i=;i<m;i++){
int u=a[i].u,v=a[i].v,w=a[i].w;
if(cost[v]>w&&u!=v){
pre[v]=u;
cost[v]=w;
}
} for(int i=;i<n;i++){
if(i==root) continue;
if(cost[i]==inf) return -;
} int cnt_circle=;
memset(id,-,sizeof(id));
memset(vis,-,sizeof(vis));
cost[root]=;
for(int i=;i<n;i++){
ans+=cost[i];
int p=i;
while(vis[p]!=i&&id[p]==-&&p!=root)
vis[p]=i,p=pre[p];
if(id[p]==-&&p!=root){
for(int u=pre[p];u!=p;u=pre[u]){
id[u]=cnt_circle;
}
id[p]=cnt_circle++;
}
}
if(!cnt_circle) break;
for(int i=;i<n;i++)
if(id[i]==-) id[i]=cnt_circle++;
for(int i=;i<m;i++){
int v=a[i].v;
a[i].u=id[a[i].u];
a[i].v=id[a[i].v];
if(a[i].u!=a[i].v){
a[i].w=a[i].w-cost[v];
}
}
n=cnt_circle;
root=id[root];
}
return ans;
}
int main()
{
int T;
int cnt=;
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);
for(int i=;i<m;i++)
scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
int ans=zhu_liu();
printf("Case #%d: ",++cnt);
if(ans==-) printf("Possums!\n");
else printf("%d\n",ans);
}
return ;
}
给出从1开始的代码;
这道题是以r为根,点是从1~n,
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn=1e4+;
const ll inf=0x3f3f3f3f3f3f3f;
struct node
{
ll u,v,w;
}a[maxn];
ll n,m; //点的个数和边的个数都要定在全局变量,因为zhuliu里用到;
ll cost[maxn],pre[maxn],vis[maxn],id[maxn];
ll zhu_liu(ll root)
{
ll ans=;
while(){
for(ll i=;i<=n;i++) cost[i]=inf; for(ll i=;i<=m;i++){
ll u=a[i].u,v=a[i].v,w=a[i].w;
if(cost[v]>w&&u!=v){
pre[v]=u;
cost[v]=w;
}
} for(ll i=;i<=n;i++){
if(i==root) continue;
if(cost[i]==inf) return -; //无法构成就输出-1;
} ll cnt_circle=;
memset(id,-,sizeof(id));
memset(vis,-,sizeof(vis));
cost[root]=;
for(ll i=;i<=n;i++){
ans+=cost[i];
ll p=i;
while(vis[p]!=i&&id[p]==-&&p!=root)
vis[p]=i,p=pre[p];
if(id[p]==-&&p!=root){
for(ll u=pre[p];u!=p;u=pre[u]){
id[u]=cnt_circle;
}
id[p]=cnt_circle++;
}
}
if(cnt_circle==) break;
for(ll i=;i<=n;i++)
if(id[i]==-) id[i]=cnt_circle++;
for(ll i=;i<=m;i++){
ll v=a[i].v;
a[i].u=id[a[i].u];
a[i].v=id[a[i].v];
if(a[i].u!=a[i].v){
a[i].w=a[i].w-cost[v];
}
}
n=cnt_circle-;
root=id[root];
}
return ans;
}
int main()
{
ll r;
while(scanf("%lld%lld%lld",&n,&m,&r)!=EOF){
for(ll i=;i<=m;i++){
scanf("%lld%lld%lld",&a[i].u,&a[i].v,&a[i].w);
}
ll ans=zhu_liu(r);
printf("%lld\n",ans);
}
return ;
}
最小树形图模板 UVA11183的更多相关文章
- HDU 2121 Ice_cream’s world II 最小树形图 模板
开始学习最小树形图,模板题. Ice_cream’s world II Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32 ...
- POJ 3164 Command Network 最小树形图模板
最小树形图求的是有向图的最小生成树,跟无向图求最小生成树有很大的区别. 步骤大致如下: 1.求除了根节点以外每个节点的最小入边,记录前驱 2.判断除了根节点,是否每个节点都有入边,如果存在没有入边的点 ...
- POJ 3164 Command Network(最小树形图模板题+详解)
http://poj.org/problem?id=3164 题意: 求最小树形图. 思路: 套模板. 引用一下来自大神博客的讲解:http://www.cnblogs.com/acjiumeng/p ...
- poj 3164(最小树形图模板)
题目链接:http://poj.org/problem?id=3164 详细可以看这里:http://www.cnblogs.com/vongang/archive/2012/07/18/259685 ...
- poj 3164 最小树形图模板!!!
/* tle十几次,最后发现当i从1开始时,给环赋值时要注意啊! 最小树形图 */ #include<stdio.h> #include<string.h> #include& ...
- poj3164最小树形图模板题
题目大意:给定一个有向图,根节点已知,求该有向图的最小树形图.最小树形图即有向图的最小生成树,定义为:选择一些边,使得根节点能够到达图中所有的节点,并使得选出的边的边权和最小. 题目算法:朱-刘算法( ...
- hdu 4009 最小树形图模板题朱刘算法
#include<stdio.h> /*思路:显然对于每个地方, 只有一种供水方式就足够了,这样也能保证花费最小, 而每个地方都可以自己挖井,所以是不可能出现无解的情况的, 为了方便思考, ...
- uva11183 最小树形图模板题
很简单的模板题,不多说了 #include<iostream> #include<cstring> #include<cstdio> #define INF 0x3 ...
- poj 3164 Command Network(最小树形图模板)
Command Network http://poj.org/problem?id=3164 Time Limit: 1000MS Memory Limit: 131072K Total Subm ...
随机推荐
- 解决并发问题的CAS思想及原理
全称为:Compare and swap(比较与交换),用来解决多线程并发情况下使用锁造成性能开销的一种机制: 原理思想:CAS(V,A,B),V为内存地址,A为预期原值,B为新值.如果内存地 ...
- Codeforces Round #623 (Div. 2) D.Recommendations 并查集
ABC实在是没什么好说的,但是D题真的太妙了,详细的说一下吧 首先思路是对于a相等的分类,假设有n个,则肯定要把n-1个都增加,因为a都是相等的,所以肯定是增加t小的分类,也就是说每次都能处理一个分类 ...
- grep/sed/awk命令查看指定时间段的日志
*grep命令 今天遇到研发要求查询定时任务(elastic-job)在14:00-14:40的日志,使用grep命令很方便: 命令: grep '时间' '日志文件名 ' 1.例如查询2020-02 ...
- 关于Oracle的使用
1.查看数据库 在sqlplus / as sysdba执行后,再执行select name from v$database; 2.执行1后继续查看该数据库下的表 select table_name ...
- cursor 把鼠标指针的形状弄成一只伸出食指的手
<span style="cursor:auto">auto</span><br> <span style="cursor:cr ...
- linux - mysql - 忘记用户名、密码
1, 关闭mysql服务 /etc/rc.d/init.d/mysqld stop 2,使用 –skip-grant-tables选项启动mysql服务 (1)打开文件 mysqld vi /etc/ ...
- Linux 环境c++ 编码转换
#include <iconv.h> //代码转换:从一种编码转为另一种编码 static int CodeConvert(char *from_charset,char *to_char ...
- mysql逻辑备份与还原工具mysqldump
(一)mysqldump介绍 mysqldump是MySQL自带的逻辑备份工具,类似于Oracle的expdp/impdp,mysqldump备份十分灵活,可以在以下级别对数据库进行备份: 实例下的所 ...
- logistic回归损失函数(非常重要,深入理解)
2.2 logistic回归损失函数(非常重要,深入理解) 上一节当中,为了能够训练logistic回归模型的参数w和b,需要定义一个成本函数 使用logistic回归训练的成本函数 为了让模型通过学 ...
- 实用 docker history
关闭安装认证, 开启tcp 端口 sudo vi /usr/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd --insecur ...