B题 Telephone Lines

https://ac.nowcoder.com/acm/contest/1055/B

中文题面:https://www.luogu.com.cn/problem/P1948

分层图最短路

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll; inline int read() {
int s = 0, w = 1; char ch = getchar();
while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
return s * w;
} const int N = 2e4 + 7; //节点数
const int M = 2e4 + 7; //路径数
const ll INF = 1e18;
ll d1[N];//d1正向图,d2反向图
struct Node {
int v;
ll cost;
bool operator < (Node b)const {
return cost > b.cost;
}
};
vector<Node> e[N];
int n, m, k; void dijkstra(int s, ll d[], int p) {
priority_queue<Node> pq;
fill(d, d + N, INF);
d[s] = 0;
pq.push(Node{ s,0 });
while (!pq.empty()) {
Node x = pq.top();
pq.pop();
if (d[x.v] < x.cost) continue; //原先这个节点花费更少 跳过
for (auto it : e[x.v]) {
int z = it.cost > p;
if (d[it.v] > x.cost + z) {
d[it.v] = x.cost + z;
pq.push(Node{ it.v,d[it.v] });
}
}
}
} int main() {
n = read(), m = read(), k = read();
for (int i = 1; i <= m; ++i) {
int u = read(), v = read(), w = read();
e[u].push_back(Node{ v, w });
e[v].push_back(Node{ u, w });
}
int l = 0, r = 1e9, ans = -1;
while (l <= r) {
int mid = l + r >> 1;
dijkstra(1, d1, mid);
if (d1[n] <= k) ans = mid, r = mid - 1;
else l = mid + 1;
}
printf("%d\n", ans);
return 0;
}

dijkstra+dp


C题 最优贸易

https://ac.nowcoder.com/acm/contest/1055/C

#include<bits/stdc++.h>
using namespace std;
#define sc(n) scanf("%c",&n)
#define sd(n) scanf("%d",&n)
#define pd(n) printf("%d\n", (n))
#define sdd(n,m) scanf("%d %d",&n,&m)
#define sddd(n,m,z) scanf("%d %d %d",&n,&m,&z)
#define pdd(n,m) printf("%d %d\n",n, m)
#define ms(a,b) memset(a,b,sizeof(a))
#define all(c) c.begin(),c.end()
#define pb push_back
#define fi first
#define se second
#define mod(x) ((x)%MOD)
#define lowbit(x) (x & (-x))
#define gcd(a,b) __gcd(a,b) typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<string> VS;
const int MOD = 1e9 + 7;
const double eps = 1e-9;
const int inf = 0x3f3f3f3f;
const int maxn = 100010; struct u {
int v, len;
};
int n, m, v[maxn], d[maxn * 3 + 1];
vector<u>G[maxn * 3 + 1]; void addEdge(int x, int y) {
G[x].push_back({ y,0 });
G[x + n].push_back({ y + n,0 });
G[x + 2 * n].push_back({ y + 2 * n,0 });
G[x].pb({ y + n,-v[x] });
G[x + n].pb({ y + 2 * n,v[x] });
} queue<int>q;
bool inq[maxn * 3 + 1]; void spfa() {
ms(d, -inf);
d[1] = 0; inq[1] = true;
q.push(1);
while (q.size()) {
int tp = q.front(); q.pop();
inq[tp] = false;
int len = G[tp].size();
for (int i = 0; i < len; i++) {
u x = G[tp][i];
if (d[x.v] < d[tp] + x.len) {
d[x.v] = d[tp] + x.len;
if (inq[x.v] == false) {
q.push(x.v);
inq[x.v] = true;
}
}
}
}
} int main() {
//freopen("in.txt","r",stdin); //调试用的
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> v[i];
for (int i = 1, x, y, z; i <= m; i++) {
cin >> x >> y >> z;
addEdge(x, y);
if (z == 2) addEdge(y, x);
}
G[n].push_back( { 3 * n + 1, 0 });
G[n * 3].push_back( { 3 * n + 1, 0 });//超级终点是3*n+1编号
n = 3 * n + 1; //把n改成超级终点的编号,方便spfa操作 spfa();
cout << d[n] << endl;
return 0;
}

D题 Roads and Planes

https://ac.nowcoder.com/acm/contest/1055/d

#include<bits/stdc++.h>
using namespace std;
#define N 25005
#define M 200005
struct Node
{
int val, pos;
friend bool operator < (Node x, Node y) {
return x.val > y.val;
}
};
struct E { int next, to, dis; } e[M];
int n, m1, m2, s, num, dfn;
int h[N], bel[N], deg[N], dis[N];
bool vis[N];
vector<int> c[N];
queue<int> que; int read()
{
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x *= f;
} void add(int u, int v, int w)
{
e[++num].next = h[u];
e[num].to = v;
e[num].dis = w;
h[u] = num;
} void dfs(int x)
{
bel[x] = dfn, vis[x] = 1, c[dfn].push_back(x);
for (int i = h[x]; i != 0; i = e[i].next)
if (!vis[e[i].to]) dfs(e[i].to);
} void dijkstra(int id)
{
priority_queue<Node> pue;
for (int i = 0; i < c[id].size(); i++) pue.push((Node) { dis[c[id][i]], c[id][i] });
while (pue.size())
{
int now = pue.top().pos;
pue.pop();
if (vis[now]) continue;
vis[now] = 1;
for (int i = h[now]; i != 0; i = e[i].next)
{
if (dis[now] + e[i].dis < dis[e[i].to])
{
dis[e[i].to] = dis[now] + e[i].dis;
if (bel[now] == bel[e[i].to]) pue.push((Node) { dis[e[i].to], e[i].to });
}
deg[bel[e[i].to]]--;
if (!deg[bel[e[i].to]] && bel[now] != bel[e[i].to]) que.push(bel[e[i].to]);
}
}
} int main()
{
cin >> n >> m1 >> m2 >> s;
for (int i = 1; i <= m1; i++)
{
int u = read(), v = read(), w = read();
add(u, v, w), add(v, u, w);
}
for (int i = 1; i <= n; i++)
if (!vis[i]) ++dfn, dfs(i);
for (int i = 1; i <= m2; i++)
{
int u = read(), v = read(), w = read();
add(u, v, w);
deg[bel[v]]++;
}
memset(vis, 0, sizeof(vis));
memset(dis, 0x3f, sizeof(dis));
dis[s] = 0, que.push(bel[s]);
for (int i = 1; i <= dfn; i++)
if (!deg[i]) que.push(i);
while (que.size())
{
int now = que.front();
que.pop();
dijkstra(now);
}
for (int i = 1; i <= n; i++)
if (dis[i] >= 1e9) printf("NO PATH\n");
else printf("%d\n", dis[i]);
}

E题 Sorting It All Out

https://ac.nowcoder.com/acm/contest/1055/e

#include<bits/stdc++.h>
using namespace std;
#define sc(n) scanf("%c",&n)
#define sd(n) scanf("%d",&n)
#define pd(n) printf("%d\n", (n))
#define sdd(n,m) scanf("%d %d",&n,&m)
#define sdcd(n,c,m) scanf("%d%c%d",&n,&c,&m)
#define sddd(n,m,z) scanf("%d %d %d",&n,&m,&z)
#define pdd(n,m) printf("%d %d\n",n, m)
#define ms(a,b) memset(a,b,sizeof(a))
#define mod(x) ((x)%MOD)
#define lowbit(x) (x & (-x)) typedef long long ll;
typedef pair<int, int> PII;
typedef vector<int> VI;
typedef vector<string> VS;
const int MOD = 10000007;
const int inf = 0x3f3f3f3f;
const int maxn = 300; int n, m;
char rel[10], ans[maxn];
int dp[maxn][maxn]; int judge() {
for (int k = 1; k <= n; ++k)
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
dp[i][j] |= dp[i][k] & dp[k][j]; int state = 1;
for (int i = 1; i <= n; i++) {
if (dp[i][i]) return -1;
for (int j = i + 1; j <= n; j++) {
if (!(dp[i][j] | dp[j][i])) state = 0;
}
}
return state;
} void get_ans()
{
for (int i = 1; i <= n; i++) {
int pos = n;
for (int j = 1; j <= n; j++)
if (dp[i][j]) pos--;
ans[pos] = char(i + 'A' - 1);
}
ans[n + 1] = 0;
} int main() {
//freopen("in.txt", "r", stdin);
//ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
while (cin >> n >> m && n && m) {
ms(dp, 0);
int state = 0, success_ans = 0, failure_ans = 0;
for (int i = 1; i <= m; i++) {
scanf("%s", rel);
if (state) continue;
int x = rel[0] - 'A' + 1;
int y = rel[2] - 'A' + 1;
dp[x][y] = 1;
state = judge();
if (state == 1 && success_ans == 0) success_ans = i;
if (state == -1) failure_ans = i;
} if (state == 1) {
get_ans();
printf("Sorted sequence determined after %d relations: %s.\n", success_ans, ans + 1);
}
else if (state == -1) {
printf("Inconsistency found after %d relations.\n", failure_ans);
}
else {
printf("Sorted sequence cannot be determined.\n");
}
}
return 0;
}

F题 Sightseeing trip

https://ac.nowcoder.com/acm/contest/1055/f

#include<bits/stdc++.h>
using namespace std;
#define ms(a,b) memset(a,b,sizeof a)
const int maxn = 310;
const int inf = 0x3f3f3f3f;
int a[maxn][maxn], d[maxn][maxn], pos[maxn][maxn];
int n, m, ans = inf;
vector<int> path; void get_path(int x, int y) {
if (pos[x][y] == 0)return;
get_path(x, pos[x][y]);
path.push_back(pos[x][y]);
get_path(pos[x][y], y);
} int main() {
//freopen("in.txt", "r", stdin);
ios::sync_with_stdio(false), cin.tie(0);
int x, y, z;
cin >> n >> m;
ms(a, 0x3f);
for (int i = 1; i <= n; ++i)a[i][i] = 0;
while (m--) {
cin >> x >> y >> z;
a[x][y] = a[y][x] = min(a[y][x], z);
} memcpy(d, a, sizeof a);
for (int k = 1; k <= n; k++) {
for (int i = 1; i < k; i++)
for (int j = i + 1; j < k; j++)
if ((long long)d[i][j] + a[j][k] + a[k][i] < ans) {
ans = d[i][j] + a[j][k] + a[k][i];
path.clear();
path.push_back(i);
get_path(i, j);
path.push_back(j);
path.push_back(k);
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
if (d[i][j] > d[i][k] + d[k][j]) {
d[i][j] = d[i][k] + d[k][j];
pos[i][j] = k;
}
}
if (ans == 0x3f3f3f3f) {
puts("No solution.");
return 0;
}
for (auto p : path)
cout << p << " ";
cout << endl;
}

G题 Cow Relays

https://ac.nowcoder.com/acm/contest/1055/g

思路:

给出一张无向连通图,求S到E经过k条边的最短路。

矩阵我不熟,看了大佬的一个式子:

把经过xx个点的最短路的邻接矩阵\(X\)和经过\(y\)个点的最短路的邻接矩阵\(Y\)合并的式子为:

\[Ai,j=min(Ai,j,Xi,k+Yk,j)
\]

把输入转成邻接矩阵后,这个邻接矩阵可以看作恰好经过一个点的最短路,然后转移n−1n−1次就可以了

矩阵相乘时,需要使用快速幂优化

AC代码

#include<bits/stdc++.h>
using namespace std;
int num[1000005], n, s, t, e, tol, x, y, z;
struct map {
int data[500][500];
map operator*(const map& other) const {
map c;
for (int k = 1; k <= tol; k++)
for (int i = 1; i <= tol; i++)
for (int j = 1; j <= tol; j++)
c.data[i][j] =
min(c.data[i][j], data[i][k] + other.data[k][j]);
return c;
}
map() { memset(data, 0x3f3f3f3f, sizeof(data)); }
} dis, ans;
inline int input() { int t; scanf("%d", &t); return t; }
int main() {
n = input() - 1, t = input(), s = input(), e = input();
for (int i = 1; i <= t; i++) {
x = input();
if (!num[y = input()])num[y] = ++tol;
if (!num[z = input()])num[z] = ++tol;
dis.data[num[y]][num[z]] = dis.data[num[z]][num[y]] = x;
}
ans = dis;
while (n) (n & 1) && (ans = ans * dis, 0), dis = dis * dis, n >>= 1;
printf("%d", ans.data[num[s]][num[e]]);
}

0x61 图论-最短路的更多相关文章

  1. HDU 5521 [图论][最短路][建图灵感]

    /* 思前想后 还是决定坚持写博客吧... 题意: n个点,m个集合.每个集合里边的点是联通的且任意两点之间有一条dis[i]的边(每个集合一个dis[i]) 求同时从第1个点和第n个点出发的两个人相 ...

  2. 图论(最短路&最小生成树)

    图论 图的定义与概念 图的分类 图,根据点数和边数可分为三种:完全图,稠密图与稀疏图. 完全图,即\(m=n^2\)的图\((m\)为边数,\(n\)为点数\()\).如: 1 1 0 1 2 1 1 ...

  3. D1图论最短路专题

    第一题:poj3660 其实是Floyed算法的拓展:Floyd-Wareshall.初始时,若两头牛关系确定则fij = 1. 对于一头牛若确定的关系=n-1,这说明这头牛的排名是确定的. 通过寻找 ...

  4. 图论最短路——spfa

    今天开始图论的最短路的最后复习,今天自己手打spfa虽然看了一眼书,但是也算是自己打出来的,毕竟很久没打了,而且还是一遍a代码下来15min左右就搞完了,成就感++.所以呢来篇博客记录一下. 香甜的黄 ...

  5. NOIP专题复习1 图论-最短路

    一.知识概述 今天我们要复习的内容是图论中的最短路算法,我们在这里讲3种最短路求法,分别是:floyd,dijkstra,spfa. 那么我们从几道例题来切入今天讲解的算法. 二.典型例题 1.热浪 ...

  6. 【GDOI】【图论-最短路】时间与空间之旅

    最近打的一场校内训练的某题原题... 题目如下: Description 公元22××年,宇宙中最普遍的交通工具是spaceship.spaceship的出现使得星系之间的联系变得更为紧密,所以spa ...

  7. bzoj 2118 墨墨的等式 - 图论最短路建模

    墨墨突然对等式很感兴趣,他正在研究a1x1+a2y2+…+anxn=B存在非负整数解的条件,他要求你编写一个程序,给定N.{an}.以及B的取值范围,求出有多少B可以使等式存在非负整数解. Input ...

  8. 图论——最短路:Floyd,Dijkstra,Bellman-Ford,SPFA算法及最小环问题

    一.Floyd算法 用于计算任意两个节点之间的最短路径. 参考了five20的博客 Floyd算法的基本思想如下:从任意节点A到任意节点B的最短路径不外乎2种可能,1是直接从A到B,2是从A经过若干个 ...

  9. NOIp2013D2T3 华容道【搜索&图论-最短路】

    题目传送门 暴力搜索 看到这道题的第一反应就是直接上$bfs$啦,也没有想到什么更加优秀的算法. 然后就是$15$分钟打了$70$分,有点震惊,纯暴力诶,这么多白给分嘛,太划算了,这可是$D2T3$诶 ...

  10. 图论--最短路--dijkstra(含路径输出)模板

    #include<iostream> #include<stack> #include<queue> #include<cstring> #includ ...

随机推荐

  1. Android 实现APP可切换多语言

    原文: Android 实现APP可切换多语言 - Stars-One的杂货小窝 如果是单独给app加上国际化,其实很容易,创建对应的国家资源文件夹即可,如values-en,values-pt,ap ...

  2. Java的构造函数

    构造函数就是名字相同,名字前面可以不加东西,要加就只能加public或者其他的访问权限,其作用是赋初值.

  3. Tensorflow2.0实战之GAN

    本文主要带领读者了解生成对抗神经网络(GAN),并使用提供的face数据集训练网络 GAN 入门 自 2014 年 Ian Goodfellow 的<生成对抗网络(Generative Adve ...

  4. C++ Qt开发:Tab与Tree组件实现分页菜单

    Qt 是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍tabWidg ...

  5. Java多线程学习(Day01)

    目录 线程简介 线程实现(重点) 线程状态 线程同步(重点) 线程通信问题 进程与线程概念 --来自百度百科的解释: 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资 ...

  6. Meta3D -- 开源的Web3D低代码平台

    大家好,Meta3D是开源的Web3D低代码平台,快速搭建Web3D编辑器,共建开放互助的web3d生态 Github 进入平台 功能演示 加入UI Control 加入Action脚本 运行&quo ...

  7. linux云服务器病毒处理

    阿里云服务器被挖矿病毒入侵,CPU跑满,需要先停止相关进程.为了根除病毒,还需要 解决系统的后门问题(这部分听从阿里云工程师的建议备份系统盘快照后重置系统,再通过快照恢复数据) 然而重置系统后依然存在 ...

  8. 在ubuntu下将virtualbox虚拟机的磁盘重设大小的方法

    1.VBoxManage modifyhd /home/beyond/xxx.vdi --resize 20480 {20480(单位:M)是你要扩容之后的总大小,/home/beyond 是你存放 ...

  9. 一些JavaSE学习过程中的思路整理(三)(主观性强,持续更新中...)

    目录 一些JavaSE学习过程中的思路整理(三)(主观性强,持续更新中...) Java线程同步的几种常见情况分析 由简单到复杂的几种单例模式写法 死锁的实现与破解 使用lambda表达式化简代码 J ...

  10. C++ 学习宝藏网站分享

    C++ 学习宝藏网站分享 1. C++ 在线参考手册 Cppreference https://zh.cppreference.com C++ 开发者必备的在线参考手册,是我最常访问的 C++ 网站之 ...