博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[bzoj2595][WC2008]游览计划/[bzoj5180][Baltic2016]Cities_斯坦纳树
阅读量:4537 次
发布时间:2019-06-08

本文共 2894 字,大约阅读时间需要 9 分钟。

游览计划 bzoj-2595 wc-2008

题目大意:、。

注释:略。


想法:裸题求斯坦纳树。

斯坦纳树有两种转移方式,设$f[s][i]$表示联通状态为$s$,以$i$为根的最小代价。

第一个转移就是$f[s][i]=f[t][i]+f[s-t][i]$。这个显然但是是针对边权的,这个题我们需要减掉多算的点权更新答案。

第二个转移是相同的$s$,即$f[s][i]=f[s][j]+E[i][j]$。

发现很像三角形不等式,用$spfa$转移即可。

代码2595

#include 
#include
#include
#include
#include
#define inf 1e9#define N 11 #define M 1050 using namespace std;char *p1,*p2,buf[100000];#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)int rd() {int x=0,f=1; char c=nc(); while(c<48) {if(c=='-') f=-1; c=nc();} while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x*f;}struct Node {int x,y,S;}pre[N][N][M];struct par {int x,y;};int a[N][N],f[N][N][M];int n,m,tot=0;int dic_x[]={0,0,1,-1};int dic_y[]={1,-1,0,0};bool vis[N][N];queue
q;void spfa(int cur){ while(!q.empty()) { par p=q.front(); q.pop(); vis[p.x][p.y]=false; for(int k=0;k<4;k++) { int wx=p.x+dic_x[k],wy=p.y+dic_y[k]; if(wx<1||wx>n||wy<1||wy>m) continue; if(f[wx][wy][cur]>f[p.x][p.y][cur]+a[wx][wy]) { f[wx][wy][cur]=f[p.x][p.y][cur]+a[wx][wy]; pre[wx][wy][cur]=(Node){p.x,p.y,cur}; if(!vis[wx][wy]) vis[wx][wy]=true,q.push((par){wx,wy}); } } }}void dfs(int x,int y,int now){ // printf("%d %d %d\n",x,y,now); vis[x][y]=1; // printf("%d %d %d\n",x,y,now); Node tmp=pre[x][y][now]; // printf("%d %d %d\n",x,y,now); if(!tmp.x&&!tmp.y) return; // printf("%d %d %d\n",x,y,now); dfs(tmp.x,tmp.y,tmp.S); // printf("%d %d %d\n",x,y,now); if(tmp.x==x&&tmp.y==y) dfs(tmp.x,tmp.y,now-tmp.S); // printf("%d %d %d\n",x,y,now);}int main(){ n=rd(),m=rd(); memset(f,0x3f,sizeof f); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { a[i][j]=rd(); if(!a[i][j]) f[i][j][1<

代码5180:

#include 
#include
#include
#include
#include
#define N 100010 #define M 200010 using namespace std; typedef long long ll;priority_queue
>q;int head[N],to[M<<1],nxt[M<<1],tot; ll val[M<<1];ll f[50][N];bool vis[50][N];char *p1,*p2,buf[100000];#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)int rd() {int x=0,f=1; char c=nc(); while(c<48) {if(c=='-') f=-1; c=nc();} while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x*f;}inline void add(int x,int y,ll z) {to[++tot]=y; val[tot]=z; nxt[tot]=head[x]; head[x]=tot;}int main(){ memset(f,0x3f,sizeof f); int n=rd(),k=rd(),m=rd(); for(int i=1;i<=k;i++) {int x=rd(); f[1<<(i-1)][x]=0;} for(int i=1;i<=m;i++) {int x=rd(),y=rd(); ll z=rd(); add(x,y,z),add(y,x,z);} int all=(1<
f[i][x]+val[j]) { f[i][to[j]]=f[i][x]+val[j]; q.push(make_pair(-f[i][to[j]],to[j])); } } } ll ans=0x3f3f3f3f3f3f3f3f; for(int i=1;i<=n;i++) ans=min(ans,f[all][i]); cout << ans << endl ; return 0;}

小结:斯坦纳树类似组合最优化问题,想法非常优秀。

转载于:https://www.cnblogs.com/ShuraK/p/10534880.html

你可能感兴趣的文章
面向接口编程详解(二)——编程实例
查看>>
解决java.lang.NoClassDefFoundError: org/apache/log4j/Level
查看>>
端口号
查看>>
mysql for macOS安装
查看>>
jquery与checkbox的checked属性的问题
查看>>
HDU5092——Seam Carving(动态规划+回溯)(2014上海邀请赛重现)
查看>>
java 格式化字符串
查看>>
[.Net]轻量ORM——Dapper
查看>>
语言基础
查看>>
C# : 操作Word文件的API - (将C# source中的xml注释转换成word文档)
查看>>
C#中字符串转换成枚举类型的方法
查看>>
psplash
查看>>
git的安装和简单使用
查看>>
Airplace平台
查看>>
TinyOS实例介绍
查看>>
我是怎么定义微服务平台?
查看>>
python random
查看>>
互联网技术
查看>>
input输入框只允许输入数字/ 数字+小数点/ 文字+字母/ 等解决方法
查看>>
【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2)...
查看>>