最近刷水太多标注一下防止它淹没在silver的水题中……我成为了本题,第一个T掉的人QAQ

【题目大意】

Bovinia设计了连接N (1 < = N < = 20,000)个农场的航班。对于任何航班,指定了其中的k个农场作为枢纽。 (1 < = K <= 200 , K < = N)。
目前,共有M种单向航班( 1 < = M < = 20,000 ),第i个航班从农场u_i至农场v_i花费d_i ( 1 < = d_i < =10,000 )美元。航班保证u_i或者v_i至少有一个是枢纽,任意两个农场至多只有一个航班,保证u_i≠v_i。
Bessie负责票务服务。共收到Q个度假请求,(1 < = Q < = 50,000),其中第i个请求是从农场a_i至农场b_i 。请帮助她计算,每个请求是否满足 ,并计算:能满足的度假请求的最小费用总和。
 
【思路】
首先我们会思考一个问题:为什么要给出中枢?显然这是一个不必要信息,即即使没有中枢本题也是可以求解的。那么只有一种可能性:优化。
显然,每个非中枢的周围必定是中枢,也就是说,中枢间可以通过直接相连,或通过一个非中枢点连接。预处理 直接相连 或 间隔一个非中枢点 相连的两个中枢的距离,然后跑Floyd得出所有中枢之间的最短路。这里写堆优化dijkstra会快一些,然而我懒。
以下灰字是我脑补出来的T掉的做法。按照我的做法我们直接进入查询,如果ab都是中枢,用预处理的信息。否则就枚举旁边的中枢再加上边长。这样最糟糕的情况是两个都不是中枢,那么两边都要枚举。由于Q很大,这些时间复杂度都累在了Q里面,药丸。果然成为了该题第一个T掉的人。
接下来处理出所有的中枢到所有节点之间的最短路。由于已知两个中枢(u,v)之间的最短路,对于从v出发抵达的下一个农场vv,很容易得到(u,vv)。
最后对于查询的(a,b),如果a是一个中枢,直接可以利用上一步处理出来的信息。否则枚举a指向的每一个中枢c和b之间的最短路,再加上ac的距离,最小的那个即为最短路。
我觉得USACO上算的时间复杂度有点诡。
【错误点】
第二次的dis[i][j]表示第i个中枢到农场j的距离,前一个是中枢的编号,后一个是农场的编号。
写的时候老是弄晕掉。结果这道题写了我将近三分之二场noip的时间。
 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXK=+;
const int MAXN=+;
const ll INF=1e12;
struct node
{
int to,dis;
};
vector<node> E[MAXN];
int n,m,k,q;
ll d[MAXK][MAXK],dis[MAXK][MAXN];
int id[MAXN],num[MAXN]; void addedge(int u,int v,int w)
{
E[u].push_back((node){v,w});
} void init()
{
scanf("%d%d%d%d",&n,&m,&k,&q);
memset(id,,sizeof(id)); for (int i=;i<=m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w);
}
for (int i=;i<=k;i++)
{
int x;
scanf("%d",&x);
id[x]=i,num[i]=x;
}
} void prep()
{
for (int i=;i<=k;i++)
for (int j=;j<=k;j++)
d[i][j]=INF;
for (int i=;i<=k;i++) d[i][i]=;
for (int i=;i<=k;i++)
{
int u=num[i];
for (int j=E[u].size()-;j>=;j--)
{
int v=E[u][j].to;
if (id[v]) d[i][id[v]]=min(d[i][id[v]],(ll)E[u][j].dis);
else
{
for (int _k=E[v].size()-;_k>=;_k--)
{
int vto=E[v][_k].to;
if (id[vto] && vto!=num[i]) d[id[u]][id[vto]]=min(d[id[u]][id[vto]],(ll)E[u][j].dis+(ll)E[v][_k].dis);
}
}
}
} for (int _k=;_k<=k;_k++)
for (int i=;i<=k;i++)
for (int j=;j<=k;j++)
if (i!=j && j!=_k && _k!=i) d[i][j]=min(d[i][j],d[i][_k]+d[_k][j]);
} void prep2()
{
for (int i=;i<=k;i++)
for (int j=;j<=n;j++) dis[i][j]=INF;
for (int i=;i<=k;i++)
for (int j=;j<=k;j++) dis[i][num[j]]=d[i][j]; for (int i=;i<=k;i++)
{
for (int _k=;_k<E[num[i]].size();_k++)//注意这里是E[num[i]]不是num[i],检查了40分钟才发现QAQ
for (int j=;j<=k;j++)
{
int to=E[num[i]][_k].to;
dis[j][to]=min(dis[j][to],d[j][i]+E[num[i]][_k].dis);
}
}
} void solve()
{
int t=;
ll totalans=;
for (int i=;i<q;i++)
{
int a,b;
scanf("%d%d",&a,&b);
ll ans=INF;
if (id[a]) ans=dis[id[a]][b];
else
{
for (int j=;j<E[a].size();j++)
{
int v=E[a][j].to;
if (id[v]) ans=min(ans,E[a][j].dis+dis[id[v]][b]);
}
}
if (ans<INF)
{
totalans+=ans;
t++;
}
}
printf("%d\n",t);
printf("%d",totalans);
} int main()
{
init();
prep();
prep2();
solve();
return ;
} /*
TLE的solve,答案是正确的QAQ
void solve()
{
int t=0;
ll totalans=0;
for (int i=1;i<=q;i++)
{
int a,b;
ll ans=INF;
scanf("%d%d",&a,&b);
if (id[a] && id[b]) ans=d[id[a]][id[b]];
else if (id[a])
{
for (int ib=0;ib<rE[b].size();ib++) ans=min(ans,d[id[a]][id[rE[b][ib].to]]+(ll)rE[b][ib].dis);
}
else if (id[b])
{
for (int ia=0;ia<E[a].size();ia++) ans=min(ans,d[id[E[a][ia].to]][id[b]]+(ll)E[a][ia].dis);
}
else
{
for (int ia=0;ia<E[a].size();ia++)
for (int ib=0;ib<rE[b].size();ib++)
{
ll now=(ll)E[a][ia].dis+(ll)rE[b][ib].dis;
now+=d[id[E[a][ia].to]][id[rE[b][ib].to]];
ans=min(ans,now);
}
}
if (ans!=INF) t++,totalans+=ans;
}
printf("%d\n",t);
printf("%lld",totalans);
}*/

【Floyd(并非水题orz)】BZOJ4093-[Usaco2013 Dec]Vacation Planning的更多相关文章

  1. bzoj 4097: [Usaco2013 dec]Vacation Planning

    4097: [Usaco2013 dec]Vacation Planning Description Air Bovinia is planning to connect the N farms (1 ...

  2. bzoj4097 [Usaco2013 dec]Vacation Planning

    Description Air Bovinia is planning to connect the N farms (1 <= N <= 200) that the cows live ...

  3. [Usaco2013 DEC] Vacation Planning

    [题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=4093 [算法] 对于k个枢纽 , 分别在正向图和反向图上跑dijkstra最短路 , ...

  4. 没讲明白的水题orz

    有一道解释程序的水题没给非计算机专业的同学讲明白orz,在这里再练一下.. 源代码完全没有缩进真是难以忍受.. p.s.懂递归就不用看了#include <stdio.h> int n = ...

  5. 变形课 HDU - 1181 【floyd传递闭包水题】

    呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规律:如果咒语是以a开头b结尾的一个 ...

  6. UESTC 30 最短路,floyd,水

    最短路 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit Statu ...

  7. Codeforces Round #190 (Div. 2) 水果俩水题

    后天考试,今天做题,我真佩服自己... 这次又只A俩水题... orz各路神犇... 话说这次模拟题挺多... 半个多小时把前面俩水题做完,然后卡C,和往常一样,题目看懂做不出来... A: 算是模拟 ...

  8. BZOJ两水题连发~(BZOJ1854&&BZOJ1191)

    前言:两题都是省选题不过水的惊人,且都可以用二分图最大匹配做哎--- 1854: [Scoi2010]游戏 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: ...

  9. BZOJ USACO 银组 水题集锦

    最近刷银组刷得好欢快,好像都是水题,在这里吧他们都记录一下吧(都是水题大家一定是道道都虐的把= =)几道比较神奇的题到时再列出来单独讲一下吧= =(其实我会说是BZOJ蹦了无聊再来写的么 = =) [ ...

随机推荐

  1. 7 SQL优化技术

    7.1 改变访问结构 7.2 修改SQL语句 SELECT deptno   FROM dept WHERE deptno NOT IN (SELECT deptno FROM emp); SELEC ...

  2. 88.modelsim仿真do文件相关技巧

    网上的关于DO文件的编写好像资料不多,比较杂,所以本人总结一下常用的简单语法,方便大家查看.其实本人也刚接触DO文件没多久,有纰漏很正常,欢迎指正批评,互相学习.PS:写得有点乱   还有一个值得注意 ...

  3. 移动端测试=== adb 无线连接手机

    无线连接(需要借助 USB 线) 除了可以通过 USB 连接设备与电脑来使用 adb,也可以通过无线连接——虽然连接过程中也有需要使用 USB 的步骤,但是连接成功之后你的设备就可以在一定范围内摆脱 ...

  4. Logback的继承体系

    今天碰到一个问题,发现控制台日志输出两遍,搜索得知,这个是由于logback继承体系导致的. logback不仅会继承level,也会继承appender,需要注意的是: <root> & ...

  5. 好用的工具---screen命令

    问 题场景:要在服务器上配置环境,但是我的电脑无法直接连到服务器上,通常要经过好几次ssh跳转.配环境需要设置好几个用户,这自然需要同时打开好几个连 接服务器的终端窗口,每个连接到服务器的终端窗口都要 ...

  6. 十二、springboot之web开发之静态资源处理

    springboot静态资源处理 Spring Boot 默认为我们提供了静态资源处理,使用 WebMvcAutoConfiguration 中的配置各种属性. 建议大家使用Spring Boot的默 ...

  7. js实现table导出Excel,保留table样式

    浏览器环境:谷歌浏览器 1.在导出Excel的时候,保存table的样式,有2种方法,①是在table的行内写style样式,②是在模板里面添加样式 2.第一种方式:行内添加样式 <td sty ...

  8. git本地分支和远程分支改名

    #1 将本地分支进行改名 git branch -m old_branch new_branch #2 将远程分支的老分支删除 git push origin :old_branch #3 将改名后的 ...

  9. Zookeeper原理架构与搭建

    一.Zookeeper到底是什么!? 学一个东西,不搞明白他是什么东西,哪还有心情学啊!! 首先,Zookeeper是Apache的一个java项目,属于Hadoop系统,扮演管理员的角色. 然后看到 ...

  10. MySQL学习笔记:limit

    MySQL支持用limit语句来设置查询的行数范围,同Hive. LIMIT a, b; a:从a+1开始: b:取b行数据: 1.取出第一行记录: ,; 2.取出第二行记录: ,; 3.取出从11开 ...