Codeforces 1321D Navigation System

题意

有个人要从\(s\)走到\(t\),经过的路径给定。导航系统每次会显示当前节点到\(t\)的最短路,有多条就显示其中之一。这个人如果按照导航走,那么啥都没变。如果没有按导航走导航就会重新导航。问重新导航的最小和最大次数。

解题思路

建反图,在反图上以\(t\)为源跑dijkstra最短路。

在原图上dfs

  • 若下一个节点到\(t\)的距离是所有邻接节点中最短的

    • 如果到\(t\)最短的节点只有一个,那么什么都不变。
    • 如果不止一个,那么最大次数加1。
  • 若下一个节点到\(t\)的距离是所有邻接节点中最短的,那么最大次数和最小次数都加1。

AC代码

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int,int> pi;

#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define endl '\n'

const double PI=acos(-1.0);

namespace IO{
    bool REOF = 1;//为0表示文件结尾
    inline char nc() {
        static char buf[100000], *p1 = buf, *p2 = buf;
        return p1 == p2 && REOF && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? (REOF = 0, EOF) : *p1++;
    }

    template<class T>
    inline bool read(T &x) {
        if(!REOF)return false;
        char c = nc();bool f = 0; x = 0;
        while (c<'0' || c>'9')c == '-' && (f = 1), c = nc();
        while (c >= '0'&&c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = nc();
        if(f)x=-x;
        return true;
    }

    template<typename T, typename... T2>
    inline bool read(T &x, T2 &... rest) {
        if(!REOF)return false;
        read(x);
        return read(rest...);
    }

    inline bool need(char &c) { return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')); }
    // inline bool need(char &c) { return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9')) || ((c >= 'A') && (c <= 'Z')) || c==' '; }

    inline bool read_str(char *a) {
        if(!REOF)return false;
        while ((*a = nc()) && need(*a) && REOF)++a; *a = '\0';
        return true;
    }

    inline bool read_dbl(double &x){
        if(!REOF)return false;
        bool f = 0; char ch = nc(); x = 0;
        while(ch<'0'||ch>'9')  {f|=(ch=='-');ch=nc();}
        while(ch>='0'&&ch<='9'){x=x*10.0+(ch^48);ch=nc();}
        if(ch == '.') {
            double tmp = 1; ch = nc();
            while(ch>='0'&&ch<='9'){tmp=tmp/10.0;x=x+tmp*(ch^48);ch=nc();}
        }
        if(f)x=-x;
        return true;
    }

    template<class TH> void _dbg(const char *sdbg, TH h){ cerr<<sdbg<<'='<<h<<endl; }

    template<class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
        while(*sdbg!=',')cerr<<*sdbg++;
        cerr<<'='<<h<<','<<' '; _dbg(sdbg+1, a...);
    }

    template<class T> ostream &operator<<(ostream& os, vector<T> V) {
        os << "["; for (auto vv : V) os << vv << ","; return os << "]";
    }

    template<class L, class R> ostream &operator<<(ostream &os, pair<L,R> P) {
        return os << "(" << P.st << "," << P.nd << ")";
    }

    #define debug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
}

using namespace IO;
const int maxn=2e5+5;
const int maxv=2e5+5;
const int mod=998244353; // 998244353 1e9+7
const int INF=1e9+7; // 1e9+7 0x3f3f3f3f 0x3f3f3f3f3f3f3f3f
const double eps=1e-12;

int dx[4]={0,1,0,-1};
//int dx[8]={1,0,-1,1,-1,1,0,-1};
int dy[4]={1,0,-1,0};
//int dy[8]={1,1,1,0,0,-1,-1,-1};

// #define ls (x<<1)
// #define rs (x<<1|1)
// #define mid ((l+r)>>1)
// #define lson ls,l,mid
// #define rson rs,mid+1,r

/**
 * **********     Backlight     **********
 * 仔细读题
 * 注意边界条件
 * 记得注释输入流重定向
 * 没有思路就试试逆向思维
 * 加油,奥利给
 */

struct Graph{
    int tot,head[maxn];
    struct Edge{
        int v,nxt;
    }e[maxn<<1];
    void init(){
        tot=1;
        memset(head,0,sizeof(head));
    }
    void addedge(int u,int v){
        e[tot].v=v;e[tot].nxt=head[u];
        head[u]=tot++;

        // e[tot].v=u;e[tot].nxt=head[v];
        // head[v]=tot++;
    }
}G1,G2;

int n,m,k,p[maxn],dis[maxn];
int mi,ma;
void dijkstra(int S){
    priority_queue<pi, vector<pi>, greater<pi> > q;
    for (int i = 1; i <= n; i++) dis[i] = INF;
    dis[S] = 0; q.push(make_pair(0, S));
    while (!q.empty()){
        pi p = q.top(); q.pop();
        if (dis[p.second] != p.first) continue;
        for (int i = G2.head[p.second]; i; i=G2.e[i].nxt){
            int v = G2.e[i].v, w=1;
            if (dis[v] > dis[p.second] + w){
                dis[v] = dis[p.second] + w;
                q.push(make_pair(dis[v], v));
            }
        }
    }
}

void dfs(int id){
    if(id==k){

        return;
    }
    int u=p[id],w=p[id+1];
    int MIN=INF,cnt=0;
    for(int i=G1.head[u];i;i=G1.e[i].nxt){
        int v=G1.e[i].v;
        if(dis[v]<MIN){
            MIN=dis[v];
            cnt=0;
        }
        if(dis[v]==MIN)cnt++;
    }

    if(dis[w]==MIN){
        if(cnt>1)ma++;
    }
    if(dis[w]>MIN){
        mi++;
        ma++;
    }
    dfs(id+1);
}

void solve(){
    read(n,m);
    int u,v;
    G1.init(); G2.init();
    for(int i=1;i<=m;i++){
        read(u,v);
        G1.addedge(u,v);
        G2.addedge(v,u);
    }
    read(k);
    for(int i=1;i<=k;i++)read(p[i]);

    dijkstra(p[k]);

    dfs(1);
    printf("%d %d\n",mi,ma);
}

int main()
{
    // freopen("in.txt","r",stdin);
    // ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    // int _T; read(_T); for(int _=1;_<=_T;_++)solve();
    // while(read(n))solve();
    solve();
    return 0;
}

原文地址:https://www.cnblogs.com/zengzk/p/12404305.html

时间: 2024-10-07 04:34:54

Codeforces 1321D Navigation System的相关文章

CodeForces 4C Registration system

Registration system Time Limit: 5000ms Memory Limit: 65536KB This problem will be judged on CodeForces. Original ID: 4C64-bit integer IO format: %I64d      Java class name: (Any) A new e-mail service "Berlandesk" is going to be opened in Berland

D. Navigation System

题目链接:http://codeforces.com/contest/1321/problem/D 题目大意: 给你一张有向图,再给你一个路径,在路径的每一步上都维护最短路,如果不是按照最短路走就更新最短路,输出最小或最大更新次数(有最小或最大是因为最短路不唯一). 想法: 反向连边跑dij,记录最短路以及最短路的条数 然而记录最短路条数需要重新正向连一次边 #include <algorithm> #include <string> #include <string.h&g

Codeforces 458A Golden System

经过计算两个字符串的大小对比 主要q^2=q+1 明明是斐波那契数 100000位肯定超LL 我在每一位仅仅取到两个以内 竟然ac了 #include<bits/stdc++.h> using namespace std; int a[100020]; char s1[100020],s2[100020]; int main() { scanf("%s%s",s1,s2); int len1=strlen(s1),len2=strlen(s2); for(int i=len

codeforces C. Booking System

题意:有n组客人,分别告诉每一组的个数和花费,然后给你餐厅内k个桌子,每个桌子的最大容纳人数,如何安排使得餐厅最大收益并且容纳人数尽可能大: 思路:贪心,对花费排序,然后对每一组客人找桌子就可以. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define maxn 2000 5 using namespace std; 6 struct node 7 { 8 int c,p,id;

Unity Manual —— Navigation and Pathfinding

一.两个问题 在Unity中,想要完成自动寻路,需要以下解决两个问题. 1.如何根据当前的level,找到目的地(how to reason about the level to find the destination) 2.如何到达该目的地(how to move there) 第一个问题是全局(globally),静态的,需要计算整个Scene: 第二个问题是局部(locally),动态的,需要实时考虑当前agent的移动方向与如何避免和其他agents发生碰撞,从而从出发点到达目的地 二

【 论文学习记录】A flexible and scalable slam system with full 3d motion estimation 一种灵活可扩展带有3D运动估计的slam系统

A flexible and scalable slam system with full 3d motion estimation   论文学习记录 这篇论文系统框架,栅格多阈值,更新同步与伪数据,扫描匹配起始点,协方差交叉融合的思想还是值得借鉴的. 摘要 关注于搜救机器人建图定位与导航的框架性文章. 低计算资源的在线快速获取栅格地图: 结合鲁棒的激光扫描匹配方法和惯性传感器姿态估计系统. 快速地图梯度近似与多分辨率(类似图像金字塔)栅格地图,精确而不需要闭环检测. 介绍 2D slam 子系

Roomblock: a Platform for Learning ROS Navigation With Roomba, Raspberry Pi and RPLIDAR(转)

What is this? "Roomblock" is a robot platform consists of a Roomba, a Raspberry Pi 2, a laser sensor(RPLIDAR) and a mobile battery. The mounting frame can be made by 3D printers. ROS navigation system enable to make a map of rooms and use it to

泡泡一分钟:Perception-aware Receding Horizon Navigation for MAVs

作为在空中抛掷四旋翼飞行器后恢复的第一步,它需要检测它使用其加速度计的发射.理想的情况下,在飞行中,加速度计理想地仅测量由于施加的转子推力引起的加速度,即.因此,当四旋翼飞行器发射时,我们可以检测到测量的加速度下降到与当前施加的推力相对应的值. B. Recovery and Initialization Steps 张宁    Perception-aware Receding Horizon Navigation for MAVs    "链接:https://pan.baidu.com/s

Codeforces Round #625

? A - Journey Planning 题意: 有一列共 n 个城市, 每个城市有美丽值b[i], 要访问一个子序列的城市, 这个子序列相邻项的原项数之差等于美丽值之差, 求最大的美丽值总和. 思路: 对于一个合法的子序列, b[i] - i 结果是一个定值, 统计该值取最大. view code #include <bits/stdc++.h> using namespace std; #define ll long long #define inc(i, l, r) for (int