zoukankan      html  css  js  c++  java
  • 【洛谷4212】外太空旅行(模拟退火)

    点此看题面

    大致题意: 给你一张图,让你从中选取最多的点,使这些点所构成的是完全图。

    模拟退火

    这道题可以用模拟退火来乱搞(或者随机化+(dfs)?)。

    大体就是搞一个序列,定义其价值为从左往右、见到合法点立刻选所能选出的点数。

    然后模拟退火,求出最大价值即为答案。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 50
    #define swap(x,y) (x^=y^=x^=y)
    #define Gmax(x,y) (x<(y)&&(x=(y)))
    using namespace std;
    int n,f[N+5][N+5];
    class SimulatedAnnealing//模拟退火
    {
    	private:
    		#define SA_TIME 100
    		int ans,s[N+5],vis[N+5];
    		I int Calc()//求出序列价值
    		{
    			RI i,j,res=0;for(i=1;i<=n;++i)
    			{
    				for(j=1;j^i;++j) if(vis[j]&&!f[s[i]][s[j]]) break;
    				i^j?vis[i]=0:(++res,vis[i]=1);
    			}return res;
    		}
    		I void Work()//模拟退火
    		{
    			RI i,x,y,res,nres;for(i=1;i<=n;++i) s[i]=i;random_shuffle(s+1,s+n+1),res=Calc(),Gmax(ans,res);//随机初始序列
    			for(double tt=1e7;tt>1e-3;tt*=0.995)
    			{
    				W((x=rand()%n+1)==(y=rand()%n+1));swap(s[x],s[y]),nres=Calc(),Gmax(ans,nres);
    				(nres>res||exp((res-nres)/tt)>1.0*rand()/RAND_MAX)?res=nres:swap(s[x],s[y]);
    			}
    		}
    	public:
    		I void Solve() {srand(20030909);for(RI i=1;i<=SA_TIME;++i) Work();printf("%d",ans);}
    }S;
    int main()
    {
    	RI i,x,y;scanf("%d",&n);W(~scanf("%d%d",&x,&y)) f[x][y]=f[y][x]=1;//读入,建图
    	return S.Solve(),0;
    }
    
  • 相关阅读:
    Kafka 生产者 自定义分区策略
    同步互斥
    poj 1562 Oil Deposits(dfs)
    poj 2386 Lake Counting(dfs)
    poj 1915 KnightMoves(bfs)
    poj 1664 放苹果(dfs)
    poj 1543 Perfect Cubes (暴搜)
    poj 1166 The Clocks (暴搜)
    poj 3126 Prime Path(bfs)
    处理机调度
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/Luogu4212.html
Copyright © 2011-2022 走看看