P3959 宝藏

原题地址 https://www.luogu.org/problemnew/show/P3959

关于随机化:

上帝不掷筛子。 ——爱因斯坦

不要指挥上帝怎么做。 ——波尔


这与自然选择类似,即有概率发生基因突变:

物竞天择,适者生存 ——Darwin

主体思路 :最小生成树,随机化

首先打一个最小生成树板子,枚举起点,得到45pts

然后根据实际情况确定循环次数,每次扩展新边时,有概率不选择最短边,而要选择较长边

#include 
#include 
#include 
#include 
using namespace std;
int m,n,x,y,l,en=0;
const int maxn=13;
const int maxm=2001;
const int maxt=1000;
const int INF=2147483640;
long long int ans=0,anse=INF;
int v2[maxn],f[maxn],a[maxn][maxn];
bool v1[maxn];
int qread(){
    int x=0;char ch=getchar();
    while(ch>'9'||ch<'0')ch=getchar();
    while(ch<='9'&&ch>='0'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x;
}
void csh(){
    for(int i=1;i<=n;i++){
    v1[i]=true;
    v2[i]=INF;
    f[i]=0;
      }
}
int main(){
   // freopen("3959_15.txt","r",stdin);
    //freopen("3959.out","w",stdout);
     n=qread();m=qread();
     for(int i=1;i<=n;i++){
       f[i]=0;
        for(int j=1;j<=n;j++){
            a[i][j]=a[j][i]=INF;
        }
     }
     for(int i=1;i<=m;i++){
        x=qread();y=qread();l=qread();
        a[x][y]=a[y][x]=min(a[x][y],l);
      }
      //for(int i=1;i<=m*2;i++)cout<
      srand(551);
       for(int TIME=1;TIME<=10000;TIME++){

        bool can=true;
        for(int st=1;st<=n;st++){
           can=true;
            ans=0;
            csh();
                 v2[st]=0;
                  int time=0;
                   while(timeint t=-1,minn=INF;
                    bool hf=true;

                    for(int i=1;i<=n;i++){
                        if(v1[i]&&v2[i]if(rand()%TIME>2000){//#12把1改为10 +500
                            t=i; minn=v2[i];
                           }
                            //  else cout<
                        } 
                       }
                       if(t<0){
                        can=false;
                        continue;
                       }
                     //  cout<
                       if(t>0)v1[t]=false;
                       //cout<
                       ans+=f[t]*v2[t];
                     for(int i=1;i<=n;i++){
                        if(v1[i]&&(a[t][i]1;
                         }
                     }
                   }

           //cout<
         //  if(ans!=anse)cout<
           if(can)anse=min(ans,anse);
           }
            //在这里把更新anse移动括号内部 
       }


            cout<return 0;
}

你可能感兴趣的:(乱搞,奇怪的做法)