这套好丧……跟别的画风好不一样(中国风?)。提答没做也没测,假装只有两题吧。140/200

T1.ROBOTS

题目大意:h*w的网格上有n个机器人编号1~n,网格上有空地、墙、顺/逆时针转向器,每次可以把一个机器人朝一个方向推,机器人碰到空地会继续前进,碰到转向器会转向,碰到墙会在前一格停止,同一时间只能有一个机器人在动,编号连续的机器人可以合体,例如2号和3号合成[2,3],[2,3]和[4,6]合成[2,6],问把所有机器人合成一个最少要推几下,无解输出-1。(n<=9,h,w<=500)

思路:先记忆化搜索预处理出每个格子朝四个方向推各会推到哪里(注意可能会无限循环),用f[i][j][k][l]表示[i,j]并成一个机器人位于(k,l)格至少要推几下(内存较紧,需要hash),考虑dijkstra,堆的log难以接受,我想了个方法:答案肯定不会太大,于是每种权值开一个队列,这样复杂度是每次转移O(1),由于还要区间合并,最后时间复杂度大概是O(n^3hw),空间同样。不过实际上这个n^3不是满的,所以理论上应该是很科学的,不过我写了vector,常数好像有点大,本来想手写个链表加上内存回收搞不好就过了,因为懒而且还要打T2暴力就放弃了,最后得分85/100(都是T)。

#include<cstdio>
#include<cstdlib>
#include<vector>
#include<queue>
using namespace std;
#define MN 500
#define MQ 11250000
struct pos{int x,y;}t[MN+][MN+][];
const int o[][]={{,-},{-,},{,},{,}};
char g[MN+][MN+];
int d[MQ+],p[][],pl[],pr[],pn,x,y,l,r;
pos work(int x,int y,int f)
{
if(t[x][y][f].x)return t[x][y][f];
t[x][y][f]=(pos){-,-};
int r;
if(g[x][y]=='.'||(g[x][y]>=''&&g[x][y]<=''))r=f;
if(g[x][y]=='A')r=f?f-:;
if(g[x][y]=='C')r=f<?f+:;
return t[x][y][f]=(g[x][y]&&g[x][y]!='x')?
work(x+o[r][],y+o[r][],r):(pos){x-o[f][],y-o[f][]};
}
inline int hash(int x,int y,int l,int r){return x<?-:((x-)*+y-)*pn+p[l][r];}
inline void dehash(int z){l=pl[z%pn];r=pr[z%pn];y=(z/=pn)%+;x=z/+;}
struct MyPQ
{
vector<queue<int> > v;int x;
void push(int x,int z)
{
if(x<||(d[x]&&d[x]<=z))return;d[x]=z;
while(v.size()<z)v.push_back(queue<int>());
v[z-].push(x);
}
inline int top(){return v[x].front();}
inline void next(){for(v[x].pop();v[x].empty()&&x<v.size();++x);if(x==v.size())puts("-1"),exit();}
inline void pop(){for(next();x>=d[v[x].front()];next());}
}q;
int main()
{
int n,w,h,i,j,k,z,zz;
scanf("%d%d%d",&n,&w,&h);--n;
for(i=;i<=h;++i)scanf("%s",g[i]+);
for(i=;i<;++i)for(j=i;j<;++j)pl[pn]=i,pr[pn]=j,p[i][j]=pn++;
for(i=;i<=h;++i)for(j=;j<=w;++j)
{
for(k=;k<;++k)work(i,j,k);
if(g[i][j]>=''&&g[i][j]<='')q.push(hash(i,j,g[i][j]-'',g[i][j]-''),);
}
while(true)
{
dehash(z=q.top());q.pop();
if(l==&&r==n)return printf("%d",d[z]-),;
for(i=;i<l;++i)if(d[zz=hash(x,y,i,l-)])q.push(hash(x,y,i,r),d[z]+d[zz]-);
for(i=;i>r;--i)if(d[zz=hash(x,y,r+,i)])q.push(hash(x,y,l,i),d[z]+d[zz]-);
for(j=;j<;++j)q.push(hash(t[x][y][j].x,t[x][y][j].y,l,r),d[z]+);
}
}

正解:双队列广搜,每种机器人先出算出可以合成它的所有小机器人在各个位置的情况,然后开两个队列,一个是按从小机器人合成的按权值排序的队列,一个是被推着走拓展出的队列,每次取最小的,这种做法理论上和我的是同阶的,不过常数上感觉比我优到不知道哪里去了。

T2.TOLL

题目大意:给出一张N点M边的带权联通无向图,每个点上有一些人,给定K条边,要求你定边权后加入原图,使得最后最小生成树上,每个人走到1号点,路径上经过的新加的边的权值和最大。(N<=100,000,M<=300,000,K<=20)

思路:暴力枚举最后保留哪些新加的边,对原图做最小生成树后,每次加入一条非树边,O(n)算出每条边被保留下最大能取的权值,并算出答案,复杂度O(MlogM+NK*2^K),得分55/100。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
inline int read()
{
int x=;char c;
while((c=getchar())<''||c>'');
for(;c>=''&&c<='';c=getchar())x=(x<<)+(x<<)+c-'';
return x;
}
#define MN 100000
#define MM 300000
#define MK 20
struct Edge{int x,y,w;}E[MM+],S[MN+],K[MK+],T[MN+];
bool cmp(Edge a,Edge b){return a.w<b.w;}
struct edge{int nx,t,w,u,f;}e[MN*+];
int n,k,f[MN+],h[MN+],en,u[MN+],p[MN+],mx[MK+];
int fa[MN+],tf[MN+],d[MN+],ps[MN+];
ll ans,fs[MN+];
int gf(int k){return f[k]?f[k]=gf(f[k]):k;}
inline void ins(int x,int y,int w,int f=)
{
e[++en]=(edge){h[x],y,w,,f};h[x]=en;
e[++en]=(edge){h[y],x,w,,f};h[y]=en;
}
void pre(int x)
{
for(int i=h[x];i;i=e[i].nx)if(!e[i].u&&e[i].t!=fa[x])
d[e[i].t]=d[x]+,fa[e[i].t]=x,tf[e[i].t]=i,pre(e[i].t);
}
void dp(int x,int fa)
{
ps[x]=p[x];fs[x]=;
for(int i=h[x];i;i=e[i].nx)if(!e[i].u&&e[i].t!=fa)
{
dp(e[i].t,x);
ps[x]+=ps[e[i].t];
fs[x]+=fs[e[i].t];
if(e[i].f)fs[x]+=(ll)mx[e[i].f]*ps[e[i].t];
}
}
void work()
{
int i,j=,x,y,z,c;
memset(f,,sizeof(int)*(n+));
for(i=;i<=k;++i)if(u[i]&&gf(K[i].x)!=gf(K[i].y))
f[gf(K[i].x)]=gf(K[i].y),T[++j]=K[i];
memset(h,,sizeof(int)*(n+));en=;
for(i=;i<n;++i)ins(S[i].x,S[i].y,S[i].w);
memset(mx,,sizeof(mx));
for(i=;i<=j;++i)
{
pre();
for(x=T[i].x,y=T[i].y,z=-;x!=y;)
if(d[x]>d[y]){if(e[tf[x]].w&&e[tf[x]].w>z)z=e[tf[x]].w,c=tf[x];x=fa[x];}
else{if(e[tf[y]].w&&e[tf[y]].w>z)z=e[tf[y]].w,c=tf[y];y=fa[y];}
e[c].u=e[c^].u=;mx[i]=z;
for(x=T[i].x,y=T[i].y;x!=y;)
if(d[x]>d[y]){if(!e[tf[x]].w)mx[e[tf[x]].f]=min(mx[e[tf[x]].f],z);x=fa[x];}
else{if(!e[tf[y]].w)mx[e[tf[y]].f]=min(mx[e[tf[y]].f],z);y=fa[y];}
ins(T[i].x,T[i].y,,i);
}
dp(,);
if(fs[]>ans)ans=fs[];
}
void dfs(int x)
{
if(x>k){work();return;}
u[x]=;dfs(x+);
u[x]=;dfs(x+);
}
int main()
{
freopen("toll.in","r",stdin);
freopen("toll.out","w",stdout);
int m,i,j;
n=read();m=read();k=read();
for(i=;i<m;++i)E[i].x=read(),E[i].y=read(),E[i].w=read();
sort(E,E+m,cmp);
for(i=j=;i<m;++i)if(gf(E[i].x)!=gf(E[i].y))
f[gf(E[i].x)]=gf(E[i].y),S[++j]=E[i];
for(i=;i<=k;++i)K[i].x=read(),K[i].y=read();
for(i=;i<=n;++i)p[i]=read();
dfs();
cout<<ans;
fclose(stdin);fclose(stdout);return ;
}

正解:一开始先把K条边边权设为0和M条边放一起跑最小生成树,K条边把最小生成树分成K+1块,每一块最后无论如何一定是连在一起的,可以缩成一个点,然后再按上面的暴力做,复杂度O(MlogM+K^2*2^K)。

APIO 2013的更多相关文章

  1. 【UOJ #108】【APIO 2013】TOLL

    http://uoj.ac/problem/108 好神的一道题啊. 原图边权互不相同是重点! 如果有一个点集,有两组边集,要求这两组边集的并集的最小生成树,可以对两组边集分别求一下最小生成树构成新的 ...

  2. 【UOJ #107】【APIO 2013】ROBOTS

    http://uoj.ac/problem/107 设\(f(l,r,i,j)\)表示\([l,r]\)中的机器人聚集到\((i,j)\)需要花的最小操作数. \(f(l,r,i,j)=\min\le ...

  3. 【BZOJ】【3205】【APIO2013】机器人robot

    斯坦纳树 好神啊……Orz zyf && PoPoQQQ 为啥跟斯坦纳树扯上关系了?我想是因为每个点(robot)都沿着树边汇到根的时候就全部合起来了吧= =这个好像和裸的斯坦纳树不太 ...

  4. 2013 Asia Changsha Regional Contest---Josephina and RPG(DP)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4800 Problem Description A role-playing game (RPG and ...

  5. SharePoint 2013: A feature with ID has already been installed in this farm

    使用Visual Studio 2013创建一个可视web 部件,当右击项目选择"部署"时报错: "Error occurred in deployment step ' ...

  6. Visual Studio 2013 添加一般应用程序(.ashx)文件到SharePoint项目

    默认,在用vs2013开发SharePoint项目时,vs没有提供一般应用程序(.ashx)的项目模板,本文解决此问题. 以管理员身份启动vs2013,创建一个"SharePoint 201 ...

  7. SharePoint 2013 create workflow by SharePoint Designer 2013

    这篇文章主要基于上一篇http://www.cnblogs.com/qindy/p/6242714.html的基础上,create a sample workflow by SharePoint De ...

  8. Install and Configure SharePoint 2013 Workflow

    这篇文章主要briefly introduce the Install and configure SharePoint 2013 Workflow. Microsoft 推出了新的Workflow ...

  9. SharePoint 2013 configure and publish infopth

    This article will simply descript how to configure and publish a InfoPath step by step. Note: To con ...

随机推荐

  1. Linux下ip配置与网络重启

    ip配置 //以下ip配置重启失效 sudo ifconfig 192.168.1.1 sudo ifconfig 192.168.1.1 netmask 255.255.255.0 网络重启 //关 ...

  2. bzoj千题计划128:bzoj4552: [Tjoi2016&Heoi2016]排序

    http://www.lydsy.com/JudgeOnline/problem.php?id=4552 二分答案 把>=mid 的数看做1,<mid 的数看做0 这样升序.降序排列相当于 ...

  3. 原生ajax的请求函数

    ajax:一种请求数据的方式,不需要刷新整个页面:ajax的技术核心是 XMLHttpRequest 对象:ajax 请求过程:创建 XMLHttpRequest 对象.连接服务器.发送请求.接收响应 ...

  4. ajax 操作

    ajax 操作 ajax呢,就是要做到在神不知鬼不觉的情况之下给服务端发送请求. ajax能干啥哩? 这,,,,: 利用AJAX可以做:1.注册时,输入用户名自动检测用户是否已经存在.2.登陆时,提示 ...

  5. vue组件详解(二)——使用props传递数据

    在 Vue 中,父子组件的关系可以总结为 props向下传递,事件向上传递.父组件通过 props 给子组件下发数据,子组件通过事件给父组件发送消息.看看它们是怎么工作的.  一.基本用法 组件不仅仅 ...

  6. 安装 go 语言环境

    操作系统: CentOS 6.9_x64 go语言版本: 1.8.3 安装go 这里直接安装二进制,其它方式请自行搜索. 1.下载并安装go 命令如下: ? 1 2 3 wget https://st ...

  7. javascript学习(4)异常处理 try-catch 和 onerror

    一.try-catch 1.样例1 1.1.源代码 1.2.执行后 2.样例2 2.1.源代码 2.2.执行后 二.onerror 1.源代码 2.执行后

  8. SpringBoot集成Mybatis

    1.创建SpringBoot工程 根据 http://www.cnblogs.com/vitasyuan/p/8765329.html 说明创建SpringBoot项目. 2.添加相关依赖 在pom. ...

  9. Spring Cloud之——Config(配置中心)

    Spring Cloud Config(配置中心) 大家好,有一段时间没有写技术博客了.由于工作上的事情,这方面很难分配时间.近几年随着服务化的兴起,一批服务化的框架应运而生,像dubbo,thrif ...

  10. Java基础语法<六> 数组 Arrays

    笔记整理 来源于<Java核心技术卷 I > <Java编程思想>   允许数组长度为0 new element[0] 数组长度为0与null不同   1. 数组拷贝 允许将一 ...