zoukankan      html  css  js  c++  java
  • luogu P3959 宝藏

    题目链接

    luogu P3959 宝藏

    题解

    开始写了个random_shuffle竟然水了70,然后退火一下就A了?
    每次做生成树的时候,随机两条边的顺序交换
    退火一下,就A了

    代码

    #include<cmath> 
    #include<cstdio> 
    #include<ctime> 
    #include<cstring> 
    #include<algorithm> 
    inline int read() { 
    	int x = 0,f = 1; 
    	char c = getchar(); 
    	while(c < '0' || c > '9')c = getchar(); 
    	while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); 
    	return x * f; 
    }
    const int maxn = 13; 
    #define INF 0x7fffffff
    int n,m;
    int mp[maxn][maxn]; 
    #define IT = 5; 
    struct node { 
    	int u,v,w,next; 
    	bool operator < (const node & a)const { 
    		return w < a.w; 
    	} 
    } E[maxn * maxn],edge[maxn * maxn]; 
    int num = 0,head[maxn]; 
    inline void add_edge(int u,int v,int w) { 
    	edge[++ num].v = v; edge[num].w = w; edge[num].next = head[u];head[u] = num; 
    } 
    int fa[maxn]; 
    int find(int x) { 
    	if(fa[x] != x) fa[x] = find(fa[x]); 
    	return fa[x]; 
    } 
    
    int f[maxn]; 
    int tot = 0; 
    int calc(int x,int fa,int num) { 
    	int ans = 0; 
    	for(int i = head[x];i;i = edge[i].next) { 
    		int v = edge[i].v; 
    		if(v == fa) continue; 
    		ans += edge[i].w * num; 
    		ans += calc(v,x,num + 1); 
    	} 
    	return ans; 
    } 
    #define T 100000
    #define delta 0.97 
    #define eps 1e-10
    int solve() { 
    	int ret = INF; 
    	for(int i = 1;i <= n;++ i) fa[i] = i,head[i] = 0;  num = 0; 
    	int cnt = 0;  
    	for(int i = 1;i <= tot;++ i) { 
    		int u = find(E[i].u),v = find(E[i].v); 
    		if(u != v) { 
    			fa[u] = v; 
    			add_edge(E[i].u,E[i].v,E[i].w); 
    			add_edge(E[i].v,E[i].u,E[i].w); 
    			cnt ++; 
    		}   
    		if(cnt == n - 1) break; 
    	} 
    	if(cnt != n - 1) return INF; 
    	for(int i = 1;i <= n;++ i) ret = std::min(ret,calc(i,i,1)); 
    	return ret; 
    } 
    int main() { 
    	srand(20010901); 
    	n = read(),m = read(); 
    	memset(mp,0x3f,sizeof mp); 
    	for(int u,v,w,i = 1;i <= m;++ i) { 
    		u = read(),v = read(),w = read(); 
    		mp[u][v] = mp[v][u] = std::min(mp[u][v],w); 
    	} 
    	for(int i = 1;i <= n;++ i) 
    		for(int j = i + 1;j <= n;++ j) 
    		if(mp[i][j] < 0x3f3f3f3f) E[++ tot] = (node) {i,j,mp[i][j]}; 
    	if(tot == 0) { 
    		printf("0"); 
    		return 0; 
    	} 
    	std::sort(E + 1,E + tot + 1); 
    	int ans = solve(); 
    	
    	for(int i = 1;i <= 200;++ i) { 
    		int now = INF; double t = T; 
    		for(;t > eps;t *= delta) { 
    			int loc1 = rand() % tot + 1,loc2 = rand() % tot + 1; 
    			std::swap(E[loc1],E[loc2]);  
    			int nxans = solve(); 
    			if(nxans < now || (exp(now - nxans / t) < (rand() / RAND_MAX))) now = nxans; 
    			else std::swap(E[loc1],E[loc2]);  
    		} 
    		ans = std::min(ans,now); 
    	} 
     	printf("%d
    ",ans); 
     	return 0; 
    } 
     
     
      
    
  • 相关阅读:
    最新版-Python和Java实现Aes相互加解密
    tasker 实现短信监听和转发 解决短信验证码登录问题
    某宁 价格爬取 python
    python 获取 某东商品评论数
    xpath 使用
    frida hook 重载函数的几种写法
    Python 爬虫遇到形如 &#x5c0f;&#x8bf4; 的编码如何转换为中文?
    python 使用 pymysql 存,改dic类型数据
    Excel甘特图制作
    关于sunlike ERP的问题解决集
  • 原文地址:https://www.cnblogs.com/sssy/p/9643345.html
Copyright © 2011-2022 走看看