• bzoj4349: 最小树形图&&bzoj2260: 商店购物


    双倍经验大法吼

    昨天发现不会最小属性图&朱刘算法啊

    吓得我赶紧补了一发

    朱刘算法模板题

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #define N 55
    #define M 2505
    
    using namespace std;
    struct edge{
    	int from,adj,next;double len;
    	edge(){}
    	edge(int _from,int _adj,int _next,double _len):from(_from),adj(_adj),next(_next),len(_len){}
    } e[M];
    int n,g[N],m;
    void AddEdge(int u,int v,double w){
    	e[++m]=edge(u,v,g[u],w);g[u]=m;
    }
    
    double in[N];
    int prep[N];
    int vis[N],stamp;
    int bl[N],cnt;
    double directed_MST(){
    	double ret=0;
    	e[0].adj=0;
    	for (;;){
    		memset(in,127,sizeof(in));
    		memset(prep,0,sizeof(prep));
    		for (int u=1;u<=n;++u)
    			for (int i=g[u];i;i=e[i].next)
    				if (e[i].len<in[e[i].adj])
    					in[e[i].adj]=e[i].len,prep[e[i].adj]=u;
    		for (int i=1;i<=n;++i) if (prep[i]) ret+=in[i];
    		memset(vis,0,sizeof(vis));vis[0]=stamp=1;
    		memset(bl,0,sizeof(bl));cnt=0;
    		for (int i=1;i<=n;++i)if (!vis[i]){
    			int u=i;
    			++stamp;
    			for (;!vis[u];u=prep[u]) vis[u]=stamp;
    			if (vis[u]==stamp){
    				++cnt;
    				for (;!bl[u];u=prep[u]) bl[u]=cnt;
    			}
    		}
    		if (!cnt) return ret;
    		for (int i=1;i<=n;++i) if (!bl[i]) bl[i]=++cnt;
    		int m0=m;
    		memset(g,0,sizeof(g));m=1;
    		for (int i=2;i<=m0;++i)
    			if (bl[e[i].from]!=bl[e[i].adj])
    				AddEdge(bl[e[i].from],bl[e[i].adj],e[i].len-in[e[i].adj]);
    		n=cnt;
    	}
    }
    
    int need[N];
    double mincost[N];
    int main(){
    	scanf("%d",&n);++n;
    	memset(g,0,sizeof(g));m=1;
    	int u,v,m0;double tmp;
    	for (int i=1;i<n;++i){
    		scanf("%lf%d",&mincost[i],&need[i]);
    		if (need[i])
    			AddEdge(n,i,mincost[i]);
    	}
    	scanf("%d",&m0);
    	while (m0--){
    		scanf("%d%d%lf",&u,&v,&tmp);
    		if (need[u]&&need[v]){
    			AddEdge(u,v,tmp);
    			mincost[v]=min(mincost[v],tmp);
    		}
    	}
    	double sum=0;
    	for (int i=1;i<=n;++i)
    		if (need[i])
    			sum+=mincost[i]*(need[i]-1);
    	printf("%.2lf
    ",sum+directed_MST());
    	return 0;
    }
    

      

  • 相关阅读:
    C#.net开发 List与DataTable相互转换
    asp.net 7.分页
    PostgreSQL 创建触发器 Trigger
    PostgreSQL 的命令行工具 psql 的常用命令
    安装SQL Server DQS 和 MDS
    Ubuntu ssh-keygen 生成公钥并添加到远程服务器上
    阿里云code基础文档
    忘记本地MySQL数据库密码的解决方法
    谷歌浏览器安装jsonview
    phpstorm汉化包
  • 原文地址:https://www.cnblogs.com/wangyurzee7/p/5311968.html
Copyright © 2020-2023  润新知