noip2017 寶藏
阿新 • • 發佈:2018-12-18
emm...之前不會打狀壓就那隨機演算法水了過去,然後畢姥爺考到計數變式題的時候才知道後悔QAQ
然後今天就二刷了一下這道毒瘤題啦....
第一份是 隨機演算法+prim 因為是很早之前寫的,所以碼風肥腸清奇...
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #include <ctime> #include <cstdlib> #define maxi 0x7fffffff using namespace std; int n,m,u,v; long long w,ans; int s[20],dis[20]; long long map[20][20]; int main() { ans=maxi; srand(time(NULL)); scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) { s[i]=i; for(int j=1;j<=n;++j) { map[i][j]=maxi; } } for(int i=1;i<=m;++i) { scanf("%d%d%d",&u,&v,&w); map[u][v]=map[v][u]=min(map[u][v],w); } for(int i=1;i<=10000;++i) { random_shuffle(s+1,s+n+1); memset(dis,0,sizeof(dis)); dis[s[1]]=1; long long sum=0; for(int j=2;j<=n;++j) { long long mini=maxi; for(int k=1;k<j;++k) { if(map[s[j]][s[k]]!=maxi&&dis[s[k]]*map[s[j]][s[k]]<mini) { mini=dis[s[k]]*map[s[j]][s[k]]; dis[s[j]]=dis[s[k]]+1; } } if(mini==maxi) { sum=maxi; break; } sum+=mini; } ans=min(ans,sum); } printf("%lld",ans); return 0; }
然後這是今天寫的 狀壓dp+dfs 一開始列舉起點,然後通過dfs來列舉有當前狀態轉移來的狀態qwq
#include <iostream> #include <algorithm> #include <cstring> #include <cstdlib> #include <cstdio> #include <cmath> #include <ctime> #define maxn 14 #define inf 1e9 using namespace std; int n,m,u,v,w,ans,maxl; int e[maxn][maxn],dis[maxn],dp[1<<maxn]; int read() { int xx=0,kk=1;char ch=' '; while(!isdigit(ch)){ch=getchar();if(ch=='-')kk=-1;} while(isdigit(ch)){xx=xx*10+ch-'0';ch=getchar();} return kk*xx; } void dfs(int s) { for(int i=0;i<=n;++i) { if(!(s&(1<<i))) continue; for(int j=0;j<=n;++j) { if(s&(1<<j)||e[i][j]==inf) continue; if(dp[s|(1<<j)]>dp[s]+(dis[i]+1)*e[i][j]) { dp[s|(1<<j)]=dp[s]+(dis[i]+1)*e[i][j]; dis[j]=dis[i]+1; dfs(s|(1<<j)); } } } } int main() { n=read(),m=read(); maxl=(1<<n)-1,ans=inf; for(int i=0;i<=n;++i) for(int j=0;j<=n;++j) if(i!=j) e[i][j]=inf; while(m--) { u=read()-1,v=read()-1,w=read(); e[u][v]=e[v][u]=min(e[u][v],w); } for(int i=0;i<n;++i) { for(int j=0;j<=maxl;++j) dp[j]=inf; dp[1<<i]=dis[i]=0; dfs(1<<i); ans=min(ans,dp[maxl]); } printf("%d",ans); return 0; }