zoukankan      html  css  js  c++  java
  • 【luogu P3959 宝藏】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3959

    我只是心血来潮想学SA(考场上骗分总行吧)。

    这个题可以状压DP、爆搜+剪枝、有意思的还是随机化搜索(是的,这个题用的不叫SA,没有降温)。

    code:

    #include <queue>
    #include <ctime>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 10000;
    const int inf = 0x7fffffff;
    int ma[13][13], deep[maxn], n, m, ans;
    struct edge{
    	int u, v;
    };	
    bool operator < (struct edge a, struct edge b)
    {
    	return deep[a.u] * ma[a.u][a.v] > deep[b.u] * ma[b.u][b.v];
    }
    int sear(int s)//s 起点 
    {
    	int cnt = 0, cost = 0;
    	bool vis[maxn];
    	edge e[maxn], now, now2;
    	priority_queue<edge> q;
    	memset(deep, 0, sizeof(deep));
    	memset(vis, 0, sizeof(vis));
    	deep[s] = 1, vis[s] = 1;
    	for(int i = 1; i <= n; i++)
    	if(ma[s][i] < inf)
    	{
    		now.u = s, now.v = i;
    		//cout<<now.u<<" "<<now.v<<endl;
    		q.push(now);
    	}
    	for(int i = 1; i <= n-1; i++)
    	{
    		now = q.top(); q.pop();
    		while(!q.empty() && ((vis[now.v] || rand()%(n) < 1)))
    		{
    			if(!vis[now.v]) e[++cnt] = now;
    			now = q.top(); q.pop();
    		}
    		vis[now.v] = 1, deep[now.v] = deep[now.u] + 1;
    		//cout<<cnt;
    		for(int i = 1; i <= cnt; i++) q.push(e[i]);
    		for(int i = 1; i <= n; i++)
    		{
    			if(ma[now.v][i] != inf && !vis[i])
    			{
    				now2.u = now.v; now2.v = i;
    				
    				q.push(now2);
    			}
    		}
    		cost += ma[now.u][now.v] * deep[now.u];
    	}
    	return cost;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i = 1; i <= n; i++)
    		for(int j = 1; j <= n; j++) ma[i][j] = inf;
    	for(int i = 1; i <= m; i++)
    	{
    		int u, v, w;
    		scanf("%d%d%d",&u,&v,&w);
    		ma[u][v] = min(w, ma[u][v]);
    		ma[v][u] = min(w, ma[v][u]);
    	}
    	srand(192608);
    	ans = inf;
    	
    	for(int i = 1; i <= 500; i++)
    	{
    		for(int j = 1; j <= n; j++)
    		ans = min(ans, sear(j));
    	}
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    分工的好处
    这是真正的随笔,无论形式还是内容。。。
    javascript 检查函数传入的实参个数和期待的形参个数是否相同的方法
    JS中比较难记的函数
    3.0 Basic Usage of Class
    0.0 Visual Studio
    2.0 Exercise of Basic Statements
    5.0 String And RegularExpressions.
    1.0 HelloWorld
    dell mini9 fluxbox 声卡的安装 和 屏幕分辨率和刷新率的调节
  • 原文地址:https://www.cnblogs.com/MisakaAzusa/p/9872986.html
Copyright © 2011-2022 走看看