POJ 3268 Silver Cow Party 题解 《挑战程序设计竞赛》

奶牛派对:有分别来自 N 个农场的 N 头牛去农场 X 嗨皮,农场间由 M 条有向路径连接。每头牛来回都挑最短的路走,求它们走的路的最大长度?
们其实都是“图”
最短路 dijkstra 解决任意两点最短路的变种
用floyd的话会TLE,\(1000^3\)复杂度果然不是盖的,另外X的编号记得减一,测试用例很恶心的,即使忘了减一也照样得出正确答案10,但是一提交就\(WA\),让我深深地感到了来自命题者的恶意:
//第一次用OJ宏定义,提交的时候注释掉前3行即可
#ifndef ONLINE_JUDGE
#pragma warning(disalbe : 4996)
#endif
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAX_V 1024
int d[MAX_V][MAX_V];//d[u][v]表示边e=(u,v)的权值,不存在的时候等于无穷大或者d[i][i] = 0
int V;//顶点数
void floyd() {
for (int k = 0; k < V; ++k)
for (int i = 0; i < V; ++i)
for (int j = 0; j < V; ++j)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
////////////////////////////////SubMain///////////////////////////////
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int M, X;
cin >> V >> M >> X;
--X;
memset(d, 0x3f, V * MAX_V * sizeof(int));
for (int i = 0; i < V; ++i)d[i][i] = 0;
while (M--) {
int A, B, T;
cin >> A >> B >> T;
--A;
--B;
d[A][B] = T;
}
floyd();
int ans = 0;
for (int i = 0; i < V; ++i)
ans = max(ans, d[i][X] + d[X][i]);
cout << ans << endl;
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif // !ONLINE_JUDGE
return 0;
}
////////////////////////////////End Sub///////////////////////////////
dijkstra是解决单源最短路问题的,稍微修改一下就可以支持任意两点最短路:
//#ifndef ONLINE_JUDGE
//#pragma warning(disable : 4996)
//#endif
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <functional>
using namespace std;
#define MAX_V 1024
// 从顶点from指向顶点to的权值为cost的边
struct edge
{
int to, cost;
edge(){}
edge(int to, int cost) : to(to), cost(cost){}
};
// first 最短路径,second顶点编号
typedef pair<int, int> P;
// 图
vector<edge> G[MAX_V];
// 最短距离
int d[MAX_V][MAX_V];
// V是顶点数,E是边数
int V, E;
// 求解从顶点s出发到所有点的最短距离
void dijkstra(int s)
{
priority_queue<P, vector<P>, greater<P> > que;
memset(d[s], 0x3f, MAX_V * sizeof(int));
d[s][s] = 0;
que.push(P(0, s));
while (!que.empty())
{
P p = que.top(); que.pop();
int v = p.second;
if (d[s][v] < p.first) continue;
for (int i = 0; i < G[v].size(); ++i)
{
edge e = G[v][i];
if (d[s][e.to] > d[s][v] + e.cost)
{
d[s][e.to] = d[s][v] + e.cost;
que.push(P(d[s][e.to], e.to));
}
}
}
}
///////////////////////////SubMain//////////////////////////////////
int main(int argc, char *argv[])
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int M, X;
cin >> V >> M >> X;
--X;
while (M--)
{
int A, B, T;
cin >> A >> B >> T;
--A;
--B;
G[A].push_back(edge(B, T));
}
for (int i = 0; i < V; ++i)
{
dijkstra(i);
}
int ans = 0;
for (int i = 0; i < V; ++i)
{
if (i == X)
{
continue;
}
ans = max(ans, d[i][X] + d[X][i]);
}
cout << ans << endl;
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return 0;
}
///////////////////////////End Sub//////////////////////////////////
| Time | 719ms |
|---|---|
| Memory | 4736kB |
| Length | 1651 |
| Lang | G++ |
| Submitted | 2020-05-14 11:15:13 |
不过上面那个实在太浪费,我只想计算起点或终点是X的路径最短路问题,可以在上面while (!que.empty())的循环里加入判断条件,还可以这么玩:
来一个反向图,交换边的起点和终点得到反向的有向图,两次dijkstra解决问题:
//#ifndef ONLINE_JUDGE
//#pragma warning(disable :4996)
//#endif // !ONLINE_JUDGE
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include<cstring>
#include <functional>
using namespace std;
#define MAX_V 10240
// 从顶点from指向顶点to的权值为cost的边
struct edge
{
int to, cost;
edge() {}
edge(int to, int cost) : to(to), cost(cost) {}
};
// first 最短路径,second顶点编号
typedef pair<int, int> P;
// 图
vector<vector<edge> > G(MAX_V);
// 反向图
vector<vector<edge> > RG(MAX_V);
// 最短距离
int d[MAX_V];
int rd[MAX_V];
// V是顶点数,E是边数
int V, E;
// 求解从顶点s出发到所有点的最短距离
void dijkstra(int s)
{
priority_queue<P, vector<P>, greater<P> > que;
memset(d, 0x3f, sizeof(d));
d[s] = 0;
que.push(P(0, s));
while (!que.empty())
{
P p = que.top(); que.pop();
int v = p.second;
if (d[v] < p.first) continue;
for (int i = 0; i < G[v].size(); ++i)
{
edge e = G[v][i];
if (d[e.to] > d[v] + e.cost)
{
d[e.to] = d[v] + e.cost;
que.push(P(d[e.to], e.to));
}
}
}
}
///////////////////////////SubMain//////////////////////////////////
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int M, X;
cin >> V >> M >> X;
--X;
while (M--)
{
int A, B, T;
cin >> A >> B >> T;
--A;
--B;
G[A].push_back(edge(B, T));
RG[B].push_back(edge(A, T));
}
dijkstra(X);
G = RG;
memcpy(rd, d, sizeof(d));
dijkstra(X);
for (int i = 0; i < V; ++i)
{
d[i] += rd[i];
}
cout << *max_element(d, d + V) << endl;
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("out.txt");
#endif
return 0;
}
///////////////////////////End Sub//////////////////////////////////
优化以后Time降到了 235ms
POJ 3268 Silver Cow Party 题解 《挑战程序设计竞赛》的更多相关文章
- POJ 3268 Silver Cow Party (最短路径)
POJ 3268 Silver Cow Party (最短路径) Description One cow from each of N farms (1 ≤ N ≤ 1000) convenientl ...
- POJ 3268 Silver Cow Party 最短路—dijkstra算法的优化。
POJ 3268 Silver Cow Party Description One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbe ...
- POJ 3268 Silver Cow Party 最短路
原题链接:http://poj.org/problem?id=3268 Silver Cow Party Time Limit: 2000MS Memory Limit: 65536K Total ...
- POJ 3268 Silver Cow Party (双向dijkstra)
题目链接:http://poj.org/problem?id=3268 Silver Cow Party Time Limit: 2000MS Memory Limit: 65536K Total ...
- POJ 3268——Silver Cow Party——————【最短路、Dijkstra、反向建图】
Silver Cow Party Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Su ...
- POJ 3268 Silver Cow Party (最短路dijkstra)
Silver Cow Party 题目链接: http://acm.hust.edu.cn/vjudge/contest/122685#problem/D Description One cow fr ...
- poj 3268 Silver Cow Party(最短路)
Silver Cow Party Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 17017 Accepted: 7767 ...
- POJ 3268 Silver Cow Party 最短路径+矩阵转换
Silver Cow Party Time Limit : 4000/2000ms (Java/Other) Memory Limit : 131072/65536K (Java/Other) T ...
- 图论 ---- spfa + 链式向前星 ---- poj 3268 : Silver Cow Party
Silver Cow Party Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 12674 Accepted: 5651 ...
- DIjkstra(反向边) POJ 3268 Silver Cow Party || POJ 1511 Invitation Cards
题目传送门 1 2 题意:有向图,所有点先走到x点,在从x点返回,问其中最大的某点最短路程 分析:对图正反都跑一次最短路,开两个数组记录x到其余点的距离,这样就能求出来的最短路以及回去的最短路. PO ...
随机推荐
- python类的赋值操作和浅拷贝
变量的赋值 只是形成了两个变量,但是还是指向同一个对象,我们来看看代码 class SWS: pass class SSN: pass class C: def __init__(self, sws, ...
- C语言已知四位数3025具有一个特殊性质:它的前两位数字30与后两位数字25之和是55,而55的平方正好等于3025。编程找出所有具有这种性质的四位数。
#include<stdio.h> void main() { int n, i, j; for (n = 1000; n < 10000; n++) { i = n / 100; ...
- 大语言模型底层架构丨带你认识Transformer
本文分享自华为云社区<大语言模型底层架构你了解多少?大语言模型底层架构之一Transfomer的介绍和python代码实现>,作者: 码上开花_Lancer . 语言模型目标是建模自然语言 ...
- 神经网络优化篇:详解训练,验证,测试集(Train / Dev / Test sets)
训练,验证,测试集 在配置训练.验证和测试数据集的过程中做出正确决策会在很大程度上帮助大家创建高效的神经网络.训练神经网络时,需要做出很多决策,例如: 神经网络分多少层 每层含有多少个隐藏单元 学习速 ...
- 踩坑:nacos启动报错提示需要设置JDK环境 ,报错:ERROR: Please set the JAVA_HOME variable in your environment, We need java(x64)! jdk8 or later is better! !!
换了个Windows11的新电脑,因为个人工作.学习需要,就重新下载了Nacos并解压使用,结果就踩了个坑,使用下面命令启动Nacos服务端时: startup.cmd -m standalone 直 ...
- Java核心知识体系8:Java如何保证线程安全性
Java核心知识体系1:泛型机制详解 Java核心知识体系2:注解机制详解 Java核心知识体系3:异常机制详解 Java核心知识体系4:AOP原理和切面应用 Java核心知识体系5:反射机制详解 J ...
- 文心一言 VS 讯飞星火 VS chatgpt (160)-- 算法导论12.4 2题
二.用go语言,请描述这样一棵有 n 个结点的二叉搜索树,其树中结点的平均深度为 O(lgn),但这棵树的高度是w(lgn).一棵有 n个结点的二叉搜索树中结点的平均深度为 O(lgn),给出这棵树高 ...
- 【C#】【IO】【Threading】【实例】工作报表前的本地数据聚合操作
<工作记录--Report> 报表前的数据获取操作是高重复性的,今天差不多完成了脚本,下述是代码: 1 // See https://aka.ms/new-console-template ...
- 【GIT-精讲】从零玩转Git-基础理论
关于版本控制 一.什么是版本控制 版本控制(Version Control Systems)版本控制(Revision control)是一种软件工程技巧 在开发的过程中,确保由不同人所编辑的同一档案 ...
- Python——第一章:循环语句while——break和continue
while True: content = input("请输入你要发送的内容(q结束):") print("发送内容:", content) 这样的代码会无限 ...