[CF827F]Dirty Arkady's Kitchen

news/2024/5/20 7:57:18 标签: CF827F, 最短路, 图论, , akagi

Description

给出一张n个点m条边的无向图,每条边有存在时间区间[li,ri],一开始一只Akagi在1号点,每个时刻她都必须要从某个点走到另一个点,每一条边所花费的时间为1,求Akagi走到点n的最小时间。
n,m<=5*1e5

Solution

听说篡改题面可以出赤城
这道题看上去没有什么下手的地方,我们挖掘一下性质。
考虑暴力,vis[i][j]表示能否在j时刻到达点i。
可以发现一条边(u,v)可以更新vis[v][t+1],vis[v][t+3],vis[v][t+5]…..vis[u][t+2],vis[u][t+4],vis[u][t+6]….
也就是说能够更新的时间的奇偶性是相同的。
我们不妨把每个点拆成两个点,一个奇点,一个偶点,然后一条边拆成四条单向边。
把这O(m)条边扔进一个里,按照最早的出现时间l从小到大排序。
然后对于一个点x,维护L[x]表示x最晚能够在哪个时刻达到。
这样可以很轻易地判断一条边是否能够更新L数组。
如果不能更新就把这条边挂在起点,等到能够更新的时候再拿出来。
可以发现这样子一条边只会访问两次,所以总复杂度为O(m log m)

Code

#include <set>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define rep(i,a,opt) for(int i=lst[a][opt];i;i=nxt[i])
using namespace std;

int read() {
    char ch;
    for(ch=getchar();ch<'0'||ch>'9';ch=getchar());
    int x=ch-'0';
    for(ch=getchar();ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    return x;
}

const int N=5*1e5+5;

int to[N<<2],nxt[N<<2],R[N<<2],lst[N][2],cnt;
void Add(int x,int y,int opt,int r) {
    to[++cnt]=y;R[cnt]=r;nxt[cnt]=lst[x][opt];lst[x][opt]=cnt;
}

int n,m,x,y,l,r,L[N][2];

struct node{
    int x,y,l,r;
    friend bool operator < (node x,node y) {return x.l<y.l;}
};

multiset<node> s;

void Extend(int x,int l,int r,int opt) {
    L[x][opt]=max(L[x][opt],r);
    rep(i,x,opt) {
        node p;
        p.x=x;p.y=to[i];
        p.l=l;p.r=R[i];
        s.insert(p);
    }
    lst[x][opt]=0;
}

int main() {
    n=read();m=read();
    if (n==1) {puts("0");return 0;}
    fo(i,1,m) {
        x=read();y=read();l=read();r=read()-1;
        node p;
        p.x=x;p.y=y;p.l=l;p.r=r-(r-l)%2;s.insert(p);
        p.x=y;p.y=x;p.l=l;p.r=r-(r-l)%2;s.insert(p);
        p.x=x;p.y=y;p.l=l+1;p.r=r-!((r-l)%2);s.insert(p);
        p.x=y;p.y=x;p.l=l+1;p.r=r-!((r-l)%2);s.insert(p);
    }
    memset(L,255,sizeof(L));
    L[1][0]=0;
    while (!s.empty()) {
        node p=*s.begin();s.erase(s.begin());
        if (p.l>p.r) continue;
        int x=p.x,y=p.y,opt=p.l&1;
        if (L[x][opt]>=p.l) {
            if (y==n) {
                printf("%d\n",p.l+1);
                return 0;
            }
            Extend(y,p.l+1,p.r+1,opt^1);
        } else Add(x,y,opt,p.r);
    }
    puts("-1");
    return 0;
}

http://www.niftyadmin.cn/n/942047.html

相关文章

【NOI2018模拟3.11】派对

Description 给定一棵n个点的树&#xff0c;求有多少种选择m个点的方法&#xff0c;使得存在一个点x&#xff0c;使得所有m个点到x的距离不超过k。 n,m<1e5 Solution 感觉自己最近智商下线的厉害啊 考虑如何使一种方案被唯一计算。 就是所有点到x的距离都<k&#x…

【NOI2018模拟3.11】猜数游戏

Description 有一个数列生成器&#xff0c;给定正整数n,m,a,b和实数p时&#xff0c;它会生成一个满足以下条件的数列&#xff1a; (1)数列长度为n&#xff1b; (2)对于数列中的每个元素&#xff0c;它有p的概率为a*rand()&#xff0c;有1-p的概率为b*rand()&#xff0c;其中…

[CF891D]Sloth

Description 给出一棵n个节点的树&#xff0c;你需要删去并加入一条边&#xff0c;使得原图仍然是一棵树&#xff0c;并且有完美匹配。 求方案数。 n<5*1e5 Solution 考虑枚举删去一条边&#xff0c;我们只需要统计某个子树内和外有多少个点可以成为匹配点。 可以设Dp…

[CF799F]Beautiful fountains rows

Description 在一个长度为m的数轴上&#xff0c;有n种球&#xff0c;每种球会出现在区间[l,r]中。 一个合法的区间满足&#xff1a;这个区间里有球&#xff0c;并且每种出现过的球都出现了奇数次 求所有合法的区间的长度之和。 n,m<2*1e5 Solution 讲课时选了这道题然…

ZJOI2018旅游记

Day 0 一大早就出发了&#xff0c;一路颓废&#xff0c;车上打飞机竟然一次通永N&#xff1f; 被某人安利回坑LOL&#xff0c;在酒店打了几把就睡了 Day 1 讲课日&#xff0c;感觉凉凉 早上刚开始的题目还是能听的&#xff0c;结果某一道tourist都fst的题直接劝退 还好有…

[WC2018]州区划分

Description 给定一张n个点m条边的无向图&#xff0c;一个点的导出子图是不合法的当且仅当其不连通&#xff0c;或者存在欧拉回路。 你现在需要把所有点划分成若干个点的导出子图&#xff0c;使得所有子图合法。 每个点有点权wi&#xff0c;一个导出子图的价值定义为其之中的…

【NOI2018模拟3.27】Yja

Description 在平面上找 n 个点, 要求这 n 个点离原点的距离分别为 r 1 ,r 2 ,…,r n . 最大化这 n 个点构成的凸包面积, 凸包上的点的顺序任意.不要求点全部在凸包上 n<8 Solution 玄学几何题其实并不是 枚举点是否出现和一个顺序&#xff0c;问题变成求max(12∑i1nr[…

【NOI2018模拟3.28】Subset

Description 给出三个排列a,b,c&#xff0c;求对于所有的下标集合S&#xff0c;求 (max(ai),max(bi),max(ci)),i⊆S的所有可能情况。 n<1e5Solution 考虑最大值所属的位置&#xff0c;显然|S|<3 |S|1的话就是n |S|2就是一个三维偏序 |S|3比较麻烦&#xff0c;考虑容…