ICPC North Central NA Contest 2018 G . Tima goes to Xentopia(最短路 空间优化 剪枝)

简介: ICPC North Central NA Contest 2018 G . Tima goes to Xentopia(最短路 空间优化 剪枝)

linkkkk

题意:

n点m mm边的图,每条边有边权和颜色,颜色有红蓝白三种,问从s ss到t tt恰好走k 1 k1k1条红边和k 2 k2k2条蓝边的最短距离。

思路:

dp[i][j][k]表示从s出发到达点i并且经过了j条红边,k条蓝边的最短距离。

转移就是普通的dijkstra转移,但是这样内存超限。

题目中有一个条件是k 1 ∗ k 2 < = 800如果我们始终把k值大的看做是红边,小的看做是蓝边,这样只需要开455 ∗ 801 ∗ 101的d p数组。

有一个剪枝就是,如果当前经过的红边> k 1或是蓝边> k 2,都一定不符合题意了,直接跳过即可,

参考博客

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;typedef unsigned long long ull;
typedef pair<ll,ll>PLL;typedef pair<int,int>PII;typedef pair<double,double>PDD;
#define I_int ll
inline ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;}
#define read read()
#define rep(i, a, b) for(int i=(a);i<=(b);++i)
#define dep(i, a, b) for(int i=(a);i>=(b);--i)
ll ksm(ll a,ll b,ll p){ll res=1;while(b){if(b&1)res=res*a%p;a=a*a%p;b>>=1;}return res;}
const int maxn=4e5+7,maxm=1e6+7,mod=1e9+7;
int n,m,k1,k2,flag=0,s,t;
struct node{
    int e,ne,w,c;
}edge[1100*2];
int h[1100],idx;
ll dp[451][801][101];
struct node1{
    ll d,id,t1,t2;
    bool operator<(const node1 &a)const{
        return d>a.d;
    }
};
priority_queue<node1>q;
void add(ll u,ll v,ll w,ll c){
    edge[idx]={v,h[u],w,c};h[u]=idx++;
}
void bfs(){
    memset(dp,-1,sizeof dp);
    dp[s][0][0]=0;
    q.push({0,s,0,0});
    while(!q.empty()){
        node1 t=q.top();q.pop();
        ll d=t.d,id=t.id,t1=t.t1,t2=t.t2;
        if(t1>k1||t2>k2) continue;
        for(int i=h[id];~i;i=edge[i].ne){
            int j=edge[i].e,w=edge[i].w,c=edge[i].c;
            int now1=0,now2=0;
            if(c==1) now1=1;
            if(c==2) now2=1;
            if(dp[j][t1+now1][t2+now2]==-1||dp[j][t1+now1][t2+now2]>dp[id][t1][t2]+w){
                dp[j][t1+now1][t2+now2]=dp[id][t1][t2]+w;
                q.push({dp[j][t1+now1][t2+now2],j,t1+now1,t2+now2});
            }
        }
    }
}
int main() {
    memset(h,-1,sizeof h);
    n=read,m=read,k1=read,k2=read;
    if(k1<k2) swap(k1,k2),flag=1;
    for(int i=1;i<=m;i++){
        ll u=read,v=read,w=read,c=read;
        if(flag){
            if(c==1) c=2;
            else if(c==2) c=1;
        }
        add(u,v,w,c);
        add(v,u,w,c);
    }
    s=read,t=read;
    bfs();
    printf("%lld\n",dp[t][k1][k2]);
    return 0;
}


目录
相关文章
|
10月前
|
C++
【PAT甲级 - C++题解】1046 Shortest Distance
【PAT甲级 - C++题解】1046 Shortest Distance
48 0
|
10月前
|
机器学习/深度学习 C++
【PAT甲级 - C++题解】1094 The Largest Generation
【PAT甲级 - C++题解】1094 The Largest Generation
45 0
|
10月前
|
C++
【PAT甲级 - C++题解】1108 Finding Average
【PAT甲级 - C++题解】1108 Finding Average
45 0
|
机器学习/深度学习 Windows
The 2022 ICPC Asia Regionals Online Contest (I)-D题题解(DFS暴搜+剪枝+打表去重+二分)
时间复杂度:O(227 + nlog(n) + T * log(n)),227是DFS打表的时间,nlog(n)是vertor排序的时间,T*log(n)是询问次数和二分搜答案的时间。(如果算错了,评论或者私信指出谢谢)
121 0
The 2022 ICPC Asia Regionals Online Contest (I)-D题题解(DFS暴搜+剪枝+打表去重+二分)
ICPC North Central NA Contest 2018 C . Rational Ratio(结论 模拟 gcd)
ICPC North Central NA Contest 2018 C . Rational Ratio(结论 模拟 gcd)
86 0
|
机器学习/深度学习 人工智能 算法
CF1446D Frequency Problem(思维 前缀和 根号分治 双指针)
CF1446D Frequency Problem(思维 前缀和 根号分治 双指针)
64 0
|
人工智能 vr&ar
SPOJ - COT Count on a tree(主席树 LCA)
SPOJ - COT Count on a tree(主席树 LCA)
70 0
[USACO | UPC] Liars and Truth Tellers | 拓展域并查集
题目描述 After spending so much time around his cows, Farmer John has started to understand their language. Moreover, he notices that among his N cows (2 ≤ N ≤ 1000 ), some always tell the truth while others always lie.
108 0
[North Central NA Contest 2018] Rational Ratio | 规律 细节模拟
Description Every (positive) rational number can be expressed as a ratio of two (positive) integers. However, in decimal form, rational numbers often have an infifinitely repeating pattern, e.g., 1/7 = 0.142857142857142857…
93 0
[North Central NA Contest 2018] Rational Ratio | 规律 细节模拟