1、4、5、6、10都是op=1的点,除4外直接通过模拟退火调参可以全部通过。
1 #include<cmath> 2 #include<ctime> 3 #include<cstdio> 4 #include<cstdlib> 5 #include<algorithm> 6 #define rep(i,l,r) for (int i=(l); i<=(r); i++) 7 using namespace std; 8 9 const int N=5010; 10 int n,m,K,op,ans,u,v,t[N][N],r[N][N],pos[N]; 11 struct E{ int u,v; }e[N]; 12 13 int sj(int l,int r){ return rand()%(r-l+1)+l; } 14 double Rand(){ return sj(0,10000)/10000.; } 15 16 int calc(){ 17 int res=0; 18 rep(i,1,n) res+=t[i][pos[i]]; 19 rep(i,1,m) res+=r[pos[e[i].u]][pos[e[i].v]]; 20 return res; 21 } 22 23 void SA(){ 24 for (double T=1e30; T>0.001; T*=0.99997){ 25 int p=sj(1,n),q=sj(1,K),ans1=ans-t[p][pos[p]]+t[p][q]; 26 rep(i,1,m){ 27 if (e[i].u==p) ans1=ans1-r[pos[p]][pos[e[i].v]]+r[q][pos[e[i].v]]; 28 if (e[i].v==p) ans1=ans1-r[pos[e[i].u]][pos[p]]+r[pos[e[i].u]][q]; 29 } 30 int delta=ans-ans1; 31 if (delta>0 || Rand()<exp(delta/T)) ans=ans1,pos[p]=q; 32 } 33 rep(i,1,1000){ 34 int p=sj(1,n),q=sj(1,K),ans1=ans-t[p][pos[p]]+t[p][q]; 35 rep(i,1,m){ 36 if (e[i].u==p) ans1=ans1-r[pos[p]][pos[e[i].v]]+r[q][pos[e[i].v]]; 37 if (e[i].v==p) ans1=ans1-r[pos[e[i].u]][pos[p]]+r[pos[e[i].u]][q]; 38 } 39 if (ans>ans1) ans=ans1,pos[p]=q; 40 } 41 } 42 43 int main(){ 44 freopen("placement5.in","r",stdin); 45 freopen("placement5.out","w",stdout); 46 srand(time(0)); 47 scanf("%d%d%d%d",&n,&m,&K,&op); 48 rep(i,1,m) scanf("%d%d",&u,&v),e[i]=(E){u,v}; 49 rep(i,1,n) rep(j,1,K) scanf("%d",&t[i][j]); 50 rep(i,1,K) rep(j,1,K) scanf("%d",&r[i][j]); 51 rep(i,1,n) pos[i]=1; ans=calc(); SA(); 52 rep(i,1,n) printf("%d ",pos[i]); puts(""); 53 return 0; 54 }