传送门

题意:有n个城市,m条双向边,给定起点和终点。求最佳路径的种数。(最佳路径指时间和费用不同时比其他某条线路大,相同时间费用算同一种)

思路:设二维数组dp[i][j]表示在第i个城市已经花费j元的最小时间。跑一遍BFS-SPFA即可。

很明显当前不是最佳的情况下不用继续迭代,所以这题还可以用树状数组优化,但是懒得写了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;

int n,m,st,ed,maxc;
int dp[105][10005];
const int MAXN=105;
const int INF=0x3f3f3f3f;
struct edge
{
    int v;
    int cost;
    int time;
    edge(int _v=0,int _cost=0,int _time=0):v(_v),cost(_cost),time(_time) {}
};
vector<edge>g[MAXN];
void addedge(int u,int v,int w,int t)
{
    g[u].push_back(edge(v,w,t));
}
struct node{
int p,c;
};
bool vis[MAXN][9905];
void SPFA()
{
    queue<node>que;
    while(!que.empty())que.pop();
    for(int i=1; i<=n; i++)
    {
        for (int j=0;j<=maxc;j++)
        {
            dp[i][j]=INF;
            vis[i][j]=0;
        }
    }
    que.push((node){st,0});
    dp[st][0]=0;
    vis[st][0]=true;
    while(!que.empty())
    {
        node r=que.front();
        que.pop();
        int p=r.p;
        int c=r.c;
        vis[p][c]=false;
        for(int i=0; i<g[p].size(); i++)
        {
            int v=g[p][i].v;
            int cc=g[p][i].cost+c;
            if (cc>maxc)
                continue;
            if(dp[v][cc]>dp[p][c]+g[p][i].time)
            {
                dp[v][cc]=dp[p][c]+g[p][i].time;
                if(!vis[v][cc])
                {
                    vis[v][cc]=true;
                    que.push((node){v,cc});
                }
            }
        }
    }
}
int main()
{
    scanf("%d%d%d%d",&n,&m,&st,&ed);
    maxc=(n-1)*100;
    for (int i=1;i<=n;i++)
        g[i].clear();
    for (int i=0;i<m;i++)
    {
        int a,b,c,d;
        scanf("%d%d%d%d",&a,&b,&c,&d);
        addedge(a,b,c,d);
        addedge(b,a,c,d);
    }
    SPFA();
    int ans=0,minn=maxc+1;
    for (int i=0;i<=maxc;i++)
    {
        if (dp[ed][i]==INF||dp[ed][i]>=minn)
            continue;
        minn=dp[ed][i];
        ans++;
    }
    printf("%d\n",ans);
    return 0;
}
Latest posts by 青鸟千秋 (see all)

CF-1025D Recovering BST(区间dp)

传送门 题意:给定n个整数,问是否能生成一棵BST(二分查找树,左子树都比它小,右子树都比它大),并且有边相连的点权的gcd>1。 思路:区间dp,dp[l][...

阅读全文

牛客网暑期多校第五场E room(费用流)

传送门 题意:有n个宿舍,每个宿舍住4个人,给定去年n个宿舍的人员构成,今年n个4人组合的情况,求最少几个人需要搬寝室。 思路:转化为最小费用最大流解...

阅读全文

HDU-4091 Zombie’s Treasure Chest(暴力)

传送门 题意:有一个容量为n的箱子,和无限多的两种珠宝,体积和价值分别是s1,v1,s2,v2,求能装下的最大价值。 思路:直接暴力枚举会TLE,先计算s1 s2的LC...

阅读全文

欢迎留言