传送门

图论模拟题。

这题直接写3个(可以压成一个)spfa" role="presentation" style="position: relative;">spfaspfa,前两个把题上的p,q" role="presentation" style="position: relative;">p,qp,q分别当做边权来跑,然后最后一次将前两次标记过两次的边边权设为0,标记过一次的边权设为1,没标记过的边权设为0就行了。

代码如下:

#include<bits/stdc++.h>
#define N 100005
#define M 500005
using namespace std;
struct Node{int v,next,w;}e1[M<<1],e2[M<<1],e[M<<1];
int first1[N],first2[N],first[N],d1[N],d2[N],p1[N],p2[N],d[N],n,m,cnt=0,cnt1=0,cnt2=0;
bool in1[N],in2[N],in[N];
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans;
}
inline void add1(int u,int v,int w){
    e1[++cnt1].v=v;
    e1[cnt1].w=w;
    e1[cnt1].next=first1[u];
    first1[u]=cnt1;
}
inline void add2(int u,int v,int w){
    e2[++cnt2].v=v;
    e2[cnt2].w=w;
    e2[cnt2].next=first2[u];
    first2[u]=cnt2;
}
inline void add(int u,int v,int w){
    e[++cnt].v=v;
    e[cnt].w=w;
    e[cnt].next=first[u];
    first[u]=cnt;
}
inline void spfa1(int s=n){
    queue<int>q;
    memset(d1,0x3f3f3f3f,sizeof(d1));
    memset(in1,false,sizeof(in1));
    d1[s]=0,q.push(s);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        in1[x]=false;
        for(int i=first1[x];i;i=e1[i].next){
            int v=e1[i].v;
            if(d1[v]>d1[x]+e1[i].w){
                d1[v]=d1[x]+e1[i].w;
                p1[v]=i;
                if(!in1[v])in1[v]=true,q.push(v);
            }
        }
    }
}
inline void spfa2(int s=n){
    queue<int>q;
    memset(d2,0x3f3f3f3f,sizeof(d2));
    memset(in2,false,sizeof(in2));
    d2[s]=0,q.push(s);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        in2[x]=false;
        for(int i=first2[x];i;i=e2[i].next){
            int v=e2[i].v;
            if(d2[v]>d2[x]+e2[i].w){
                d2[v]=d2[x]+e2[i].w;
                p2[v]=i;
                if(!in2[v])in2[v]=true,q.push(v);
            }
        }
    }
}
inline void spfa(int s=1){
    queue<int>q;
    memset(d,0x3f3f3f3f,sizeof(d));
    memset(in,false,sizeof(in));
    d[s]=0,q.push(s);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        in[x]=false;
        for(int i=first[x];i;i=e[i].next){
            int v=e[i].v,w=e[i].w;
            if(p1[x]==i)--w;
            if(p2[x]==i)--w;
            if(d[v]>d[x]+w){
                d[v]=d[x]+w;
                if(!in[v])in[v]=true,q.push(v);
            }
        }
    }
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=m;++i){
        int u=read(),v=read(),p=read(),q=read();
        add1(v,u,p),add2(v,u,q),add(u,v,2);
    }
    spfa1(),spfa2(),spfa();
    printf("%d",d[n]);
    return 0;
}

最新文章

  1. 字符串驱动技术—— MethodAddress , MethodName , ObjectInvoke
  2. FastReport调用Delphi中的自定义函数(人民币大写金额)mtm
  3. eclipse下使用git下载和上传项目
  4. NYOJ 93 汉诺塔(三)
  5. 题解西电OJ (Problem 1005 -跳舞毯)--动态规划
  6. Visual C#使用DirectX实现视频播放
  7. Grunt Server:Fatal error: Port 35729 is already in use by another process.
  8. C#析构函数,类运行结束后运行
  9. STL中,迭代器的分类
  10. Myeclipse程序调试快捷键及步骤详解
  11. xml概述(1)
  12. HTTP协议的简单介绍
  13. java基础复习(1)
  14. Python全栈之路----数据类型—字典
  15. xss攻击问题以及如何防范
  16. Mac OSX上卸载Anaconda
  17. 【vue】vue.js安装教程/vue项目搭建
  18. 【算法】—— 1到n中减少了一个数,顺序被打乱,找出缺失的数
  19. 两种方法设置nginx并发限制下面的白名单策略
  20. Servlet不是线程安全的。

热门文章

  1. .NET MVC 两种视图引擎(Razor、Aspx)
  2. DOM对象模型
  3. (Python)numpy的argmax用法
  4. C++之继承与多态
  5. Swift 4 新特性
  6. 协变(covariance),逆变(contravariance)与不变(invariance)
  7. C#中导出EXCEL服务器端不用安装OFFICE
  8. DOS中命令的格式
  9. 利用python实现二分法和斐波那契序列
  10. 分割回文串 II &#183; Palindrome Partitioning II