P3959 [NOIP2017 提高组] 宝藏

:::dfs指数级 所以 循环区间 提前判断函数 优化都有极大 效果 与分数
#include <cstdio> using namespace std; int a[55], l[55]; int cost[55][55]; int ans = 2147483645, tmp, n, m; #define getchar() (S==T&&(T=(S=BB)+fread(BB,1,1<<15,stdin),S==T)?EOF:*S++) char BB[1 << 16], *S = BB, *T = BB; inline int read () { int X = 0; char ch = 0; while(ch < 0 || ch > 9) ch = getchar(); while(ch >= 0 && ch <= 9) X = X * 10 + ch - '0', ch = getchar(); return X; } inline int min(int a, int b) { int c = (a - b) >> 31; return a ^ c | b ^ ~c; } inline void dfs(int e, int num) { if(num == n) { ans = min(tmp, ans); return; } if(tmp >= ans) return; for(int i = 1; i <= n; i ++) {//确定下一步扩展谁 if(l[i]) continue; for(int j = 1; j <= n; j ++) {//由谁扩展 if(cost[j][i] == 2147483645 || !l[j] || i == j) continue; tmp += l[j] * cost[j][i]; l[i] = l[j] + 1; dfs(i, num + 1); tmp -= l[j] * cost[j][i]; l[i] = 0; } } } int main() { int u, v; n = read(); m = read(); for(int i = 1; i <= n; i ++) for(int j = 1; j <= n; j ++) cost[i][j] = 2147483645; for(int i = 1; i <= m; i ++) u = read(), v = read(), cost[u][v] = cost[v][u] = min(cost[u][v], read()); for(int i = 1; i <= n; i ++) { l[i] = 1; dfs(i, 1); l[i] = 0; } printf("%lld\n", ...); return 0; }
#include<cstdio> #include<iostream> #include<algorithm> //#include<queue> //#include<vector> //#include<bits/stdc++.h> #define ll long long #define ddd printf("-----------------------\n"); using namespace std; const int maxn=1e3+10 ; int n,m,c[maxn][maxn],g[maxn][maxn],d[maxn],vis[maxn],cnt,tmp,lev[maxn]; int p,ans=0x3f3f3f3f,res; bool cmp(int a,int b){//sort 依据 return c[p][a]<c[p][b]; } void dfs(int x,int node) { if(cnt>=n){ ans=min(ans,res); return; } for(int i=x;i<=cnt;i++) { if(res+tmp*lev[vis[i]]>=ans) return;//>= for(int j=node;j<=d[vis[i]];j++) { if(lev[ g[vis[i]][j] ]==0){ lev[g[vis[i]][j]]=lev[vis[i]]+1; vis[++cnt]=g[vis[i]][j]; tmp-=c[vis[cnt]][ g[vis[cnt]][1] ]; res+=lev[vis[i]]*c[vis[i]][vis[cnt]];//起点距离*线路长度 dfs(i,j+1); lev[g[vis[i]][j]]=0; tmp+=c[vis[cnt]][ g[vis[cnt]][1] ]; res-=lev[vis[i]]*c[vis[i]][vis[cnt]]; cnt--; } } node=1; } } int main() { ios::sync_with_stdio(false); //memsest(c,0x3f3f3f3f,sizeof(c)); cin>>n>>m; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) c[i][j]=0x3f3f3f3f; for(int i=1;i<=m;i++) { int u,v,val;cin>>u>>v>>val; if(c[u][v]<val) continue; if(c[u][v]==0x3f3f3f3f) g[u][++d[u]]=v,g[v][++d[v]]=u; c[u][v]=c[v][u]=val; } for(int i=1;i<=n;i++) { p=i; sort(g[i]+1,g[i]+1+d[i],cmp);//sort 对象 tmp+=c[i][ g[i][1] ]; } for(int i=1;i<=n;i++) { lev[i]=1;cnt=1;res=0; vis[1]=i; tmp-=c[i][g[i][1]]; dfs(1,1); tmp+=c[i][g[i][1]]; lev[i]=0; //cnt vis } cout<<ans<<'\n'; return 0; }

浙公网安备 33010602011771号