WIKIOI 1344 線型網絡 題解與分析

【題目鏈接】:

           http://www.wikioi.com/problem/1344/

【分析】:

        隨機化搜索,不加隨機只能過6個點。首先,預處理若ij毗鄰的距離和,然後設定循環執行次數<即人品夠好設定一次循環就能過......> ,每次隨機一個編號數組node,然後在node角標i,j滿足i<j中任意數對判斷:<令x1=node[i],y1=node[j]>如果x1前面那個數和y1毗鄰,以及y1後面那個數與x1毗鄰更優,就可以將x1-y1區間的數以對稱軸對稱調轉區間內的所有數,並設定標記,表示進行過這一步,若沒有執行過這一步,說明現在的排序方法爲本序列最優,統計答案,最後與標準最優答案比較輸出最小即可

 

【代碼】:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<time.h>
using namespace std;
#define MAX 23
#define IMAX 21474836
#define MAXSTEP 5//卡出的 
struct POINT{double x,y;};
POINT a[MAX];
int N,node[MAX];
double ans=IMAX,dist[MAX][MAX],ans1;
double DIST(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}
void swap(int &x1,int &y1){int t=x1;x1=y1,y1=t;}
bool check(int x1,int y1)
{
      if(dist[node[x1-1]][node[x1]]+dist[node[y1]][node[y1+1]]>dist[node[x1-1]][node[y1]]+dist[node[x1]][node[y1+1]])//如果x1前面那個數和y1毗鄰,以及y1後面那個數與x1毗鄰更優,就可以將x1-y1區間的數以對稱軸對稱調轉區間內的所有數 
            return true;
      return false;
}
void change(int x1,int y1)//調轉區間數 
{
      while(x1<y1)
      {
            swap(node[x1],node[y1]);
            x1++;
            y1--;
      }
}
void work()
{
      bool sign=true;
      for(int i=1;i<=N;i++)
            node[i]=i;
      for(int i=1;i<=N;i++)//隨機序列 
      {
            int num=rand()%(N-i+1)+i;
            swap(node[i],node[num]);
      }
      while(sign)
      {
            sign=false;
            for(int i=1;i<=N;i++)
                  for(int j=i+1;j<=N;j++)
                  {
                        if(check(i,j))
                        {
                              change(i,j); 
                              sign=true;
                        } 
                  }      
      }
}
int main()
{
	  scanf("%d",&N);
      for(int i=1;i<=N;i++)
            scanf("%lf%lf",&a[i].x,&a[i].y);
      srand(time(NULL));
      for(int i=1;i<=N;i++)//預處理ij毗鄰的距離 
            for(int j=1;j<=N;j++)
                  dist[i][j]=DIST(a[i].x,a[i].y,a[j].x,a[j].y);
                  
      for(int i=1;i<=MAXSTEP;i++)//限定隨機次數 
      {
            ans1=0;
            work();
            for(int j=1;j<N;j++)//統計答案 
                  ans1+=dist[node[j]][node[j+1]];
            ans=min(ans,ans1);
      }
      printf("%.2lf\n",ans);
      return 0;
}


 

轉載註明出處:http://blog.csdn.net/u011400953

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章