【思维题 并查集 图论】bzoj1576: [Usaco2009 Jan]安全路经Travel
有趣的思考题
Description
Input
* 第一行: 两个空格分开的数, N和M
* 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i
Output
* 第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最短路经上最后一条牛路的最少的时间.如果这样的路经不存在,输出-1.
题目分析
做法一
暴力树剖线段树
做法二
并查集[bzoj1576] [Usaco2009 Jan]安全路经Travel
#include<bits/stdc++.h>
const int maxn = ;
const int maxm = ; int n,m,dis[maxn];
struct cmp
{
bool operator ()(int a, int b) const
{
return dis[a] > dis[b];
}
};
struct Edge
{
int y,val;
Edge(int a=, int b=):y(a),val(b) {}
}edges[maxm];
struct EdgeSv
{
int x,y,dis;
bool operator < (EdgeSv a) const
{
return dis < a.dis;
}
EdgeSv(int a=, int b=, int c=):x(a),y(b),dis(c) {}
}edgeSv[maxm];
int fa[maxn],fat[maxn],tag[maxn],dep[maxn];
bool disVis[maxn],treeTag[maxm];
int edgeTot,svTot,nxt[maxm],pre[maxm],head[maxn];
std::priority_queue<int, std::vector<int>, cmp> q; int read()
{
char ch = getchar();
int num = ;
bool fl = ;
for (; !isdigit(ch); ch = getchar())
if (ch=='-') fl = ;
for (; isdigit(ch); ch = getchar())
num = (num<<)+(num<<)+ch-;
if (fl) num = -num;
return num;
}
void addedge(int u, int v)
{
int c = read();
edges[++edgeTot] = Edge(v, c), nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = Edge(u, c), nxt[edgeTot] = head[v], head[v] = edgeTot;
}
int get(int x){return fa[x]==x?x:fa[x]=get(fa[x]);}
int main()
{
memset(dis, 0x3f3f3f3f, sizeof dis);
memset(head, -, sizeof head);
n = read(), m = read();
for (int i=; i<=n; i++) fa[i] = i;
for (int i=; i<=m; i++) addedge(read(), read());
dis[] = , q.push();
while (q.size())
{
int tt = q.top();
q.pop();
for (int i=head[tt]; i!=-; i=nxt[i])
if (dis[edges[i].y] > dis[tt]+edges[i].val){
dis[edges[i].y] = dis[tt]+edges[i].val;
dep[edges[i].y] = dep[tt]+, pre[edges[i].y] = i, fat[edges[i].y] = tt;
q.push(edges[i].y);
}
}
for (int i=; i<=n; i++) treeTag[pre[i]] = ;
for (int i=; i<=edgeTot; i+=)
if (!treeTag[i]&&!treeTag[i+]){
int u = edges[i].y, v = edges[i+].y;
edgeSv[++svTot] = EdgeSv(u, v, edges[i].val+dis[u]+dis[v]);
}
std::sort(edgeSv+, edgeSv+svTot+);
for (int i=; i<=svTot; i++)
{
int u = edgeSv[i].x, v = edgeSv[i].y, lstu = , lstv = ;
int topu = get(u), topv = get(v);
while (topu!=topv)
{
if (dep[topu] < dep[topv])
std::swap(u, v), std::swap(lstu, lstv), std::swap(topu, topv);
if (!tag[u]){
tag[u] = i;
if (lstu) fa[lstu] = u;
}else if (lstu) fa[lstu] = topu;
lstu = topu, u = fat[topu], topu = get(u);
}
}
for (int i=; i<=n; i++)
if (!tag[i]) puts("-1");
else printf("%d\n",edgeSv[tag[i]].dis-dis[i]);
return ;
}
END
【思维题 并查集 图论】bzoj1576: [Usaco2009 Jan]安全路经Travel的更多相关文章
- BZOJ1576: [Usaco2009 Jan]安全路经Travel(最短路 并查集)
题意 给你一张无向图,保证从1号点到每个点的最短路唯一.对于每个点求出删掉号点到它的最短路上的最后一条边(就是这条路径上与他自己相连的那条边)后1号点到它的最短路的长度 Sol emmm,考场上想了个 ...
- [BZOJ1576] [Usaco2009 Jan]安全路经Travel(堆优化dijk + (并查集 || 树剖))
传送门 蒟蒻我原本还想着跑两边spfa,发现不行,就gg了. 首先这道题卡spfa,所以需要用堆优化的dijkstra求出最短路径 因为题目中说了,保证最短路径有且只有一条,所以可以通过dfs求出最短 ...
- BZOJ1576: [Usaco2009 Jan]安全路经Travel(树链剖分)
Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数 ...
- BZOJ1576 [Usaco2009 Jan]安全路经Travel
首先用Dijkstra做出最短路生成树,设dis[p]为1到p点的最短路长度 对于一条不在生成树上的边u -> v,不妨设fa为u.v的lca 则一fa到v的路径上的任意点x都可以由u达到,走的 ...
- 【BZOJ1576】[Usaco2009 Jan]安全路经Travel 最短路+并查集
[BZOJ1576][Usaco2009 Jan]安全路经Travel Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, ...
- bzoj 1576: [Usaco2009 Jan]安全路经Travel 树链剖分
1576: [Usaco2009 Jan]安全路经Travel Time Limit: 10 Sec Memory Limit: 64 MB Submit: 665 Solved: 227[Sub ...
- BZOJ.1576.[Usaco2009 Jan]安全路经Travel(树形DP 并查集)
题目链接 BZOJ 洛谷 先求最短路树.考虑每一条非树边(u,v,len),设w=LCA(u,v),这条边会对w->v上的点x(x!=w)有dis[u]+dis[v]-dis[x]+len的距离 ...
- bzoj 1576: [Usaco2009 Jan]安全路经Travel——并查集+dijkstra
Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数 ...
- 【BZOJ】1576 [Usaco2009 Jan]安全路经Travel
[算法]最短路树+(树链剖分+线段树)||最短路树+并查集 [题解] 两种方法的思想是一样的,首先题目限制了最短路树唯一. 那么建出最短路树后,就是询问对于每个点断掉父边后重新找路径的最小值,其它路径 ...
随机推荐
- plsql developer 执行sql 文件
用 Command Window,执行 @'sql file path' 注意,上面sql文件路径要加单引号
- IOS 打包提示错误(ERROR ITMS-90125: ERROR ITMS-90087: ERROR ITMS-90209:)
提示这种错误是集成环信造成的,解决方法看环信的官方文档: 集成动态库上传AppStore 由于 iOS 编译的特殊性,为了方便开发者使用,我们将 i386 x86_64 armv7 arm64 几个平 ...
- 安卓第四次作业——简单校园二手交易APP
一.项目团队 团队成员 姓名:汤文涛 学号:1600802129 班级:计算机164班 博客地址:https://www.cnblogs.com/taotao01/ 姓名:杨圣豪 学号:1600802 ...
- HDU 1114 Piggy-Bank 完全背包 dp
http://acm.hdu.edu.cn/showproblem.php?pid=1114 完全背包的题目,要求输出最小价值.然后一定要把给出的背包重量全部用完. 就是问一个背包为k的大小,n件物品 ...
- 关于Memcache的连接
addServer 在说Memcache的长连接(pconnect)和短连接(connect)之前要先说说Memcache的addServer,Memcache的addServer是增加一个服务器到连 ...
- Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead: http://mongoosejs.com/docs/promises.html
操作数据库的时候,老是提示:Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your ow ...
- 第二十章 排查和调试Web程序 之 设计异常处理策略
1. 概述 本章内容包括: 多层架构中的异常处理.使用global.asax 或 自定义的HttpHandler 或 web.config中的属性来显示特定的错误页.处理 first chance 异 ...
- [转]c# 泛类型(泛型) 以及强类型与弱类型的 理解及优化
[泛型的概念](1)没有泛型的时候,所有的对象都是以object为基础,如果要使用时必须进行强制类型转换,如果对于值类型,则会导致不断拆箱装箱的过程,对系统消耗很大.(2)使用泛型时不需要通过obje ...
- IO(转换流、缓冲流)
第1章 转换流 在学习字符流(FileReader.FileWriter)的时候,其中说如果需要指定编码和缓冲区大小时,可以在字节流的基础上,构造一个InputStreamReader或者Output ...
- python中的uuid4
Help on function uuid4 in module uuid: uuid4() Generate a random UUID.