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; 
    } 
     
     
      
    
  • 相关阅读:
    如何将网格式报表打印成其它样式
    拥有与实力不相称的脾气是种灾难——北漂18年(23)
    8.8.1 Optimizing Queries with EXPLAIN
    mysql 没有rowid 怎么实现根据rowid回表呢?
    secondary index
    8.5.5 Bulk Data Loading for InnoDB Tables 批量数据加载
    mysql 中key 指的是索引
    8.5.4 Optimizing InnoDB Redo Logging 优化InnoDB Redo 日志
    8.5.3 Optimizing InnoDB Read-Only Transactions 优化InnoDB 只读事务
    8.5.1 Optimizing Storage Layout for InnoDB Tables InnoDB表的存储布局优化
  • 原文地址:https://www.cnblogs.com/sssy/p/9643345.html
Copyright © 2011-2022 走看看