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;
    }
    
  • 相关阅读:
    面试题(三)
    面试题(二)
    经典面试题(一)
    $.ajax()实现简单计算器
    [hdu5373 The shortest problem]模拟
    [hdu5371 Hotaru's problem]最大回文半径
    [hdu5372 Segment Game]树状数组
    [zoj3813]Alternating Sum 公式化简,线段树
    [hdu5348]图上找环,删环
    [hdu5360]贪心
  • 原文地址:https://www.cnblogs.com/MisakaAzusa/p/9872986.html
Copyright © 2011-2022 走看看