POJ3463 Sightseeing(求最短路与次短路次数之和)

又是一天多校 签到都没签成 杭电的也太难了
下午也迷迷糊糊的 整个人都很晕
卡这道题卡了好久一直没输出
后来发现是有个数定的是int 但输出的时候写的是lld忘记改了
头疼
最近不怎么在状态

题目思路

根据题意 我们要维护的是最短路和严格次短路和他们对应的次数
跑最短路时情况分成4种
1等于最短路 需要更新最短路的次数
2小于最短路 需要更新最短路 最短路次数 次短路 次短路次数
3小于次短路 大于最短路 需要更新次短路 次短路次数
4等于次短路 需要更新次短路次数
按照这四种更新方式跑最短路就好了
不过跟新的时候需要细心些
不然很容易出一些小bug
浪费时间精力

ac代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <vector>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <utility>
#define pi 3.1415926535898
#define ll long long
#define lson rt<<1
#define rson rt<<1|1
#define eps 1e-6
#define ms(a,b) memset(a,b,sizeof(a))
#define legal(a,b) a&b
#define print1 printf("111\n")
using namespace std;
const int maxn = 3e5+10;
const int inf = 0x3f3f3f3f;
const ll llinf =0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;

int dis[maxn][3],cnt[maxn][3];
int vis[maxn][3],first[maxn],len;
int n,m;

struct node
{
    int to,next;
    int v;
}e[maxn];

void add(int u,int v,int w)
{
    e[len].to=v;
    e[len].v=w;
    e[len].next=first[u];
    first[u]=len++;
}

struct point
{
    int id;
    int val,t;
    point(int id,int val,int t)
    {
        this->id=id;
        this->val=val;
        this->t=t;
    }
    bool operator<(const point&x)const
    {
        return val>x.val;
    }
};

void dij(int s)
{
    memset(dis,inf,sizeof(dis));
    memset(cnt,0,sizeof(cnt));
    memset(vis,0,sizeof(vis));
    priority_queue<point>q;
    q.push(point(s,0,0));
    dis[s][0]=0;
    cnt[s][0]=1;
    while(!q.empty())
    {
        point tem=q.top();
        q.pop();
        int rt=tem.id;
        if(vis[rt][tem.t])continue;
        vis[rt][tem.t]=1;

        for(int i=first[rt];i!=-1;i=e[i].next)
        {
            int id=e[i].to;
            int len1=tem.val+e[i].v;
            //print1;
            if(len1==dis[id][0]) cnt[id][0]+=cnt[rt][tem.t];
            else if(len1<dis[id][0])
            {
                dis[id][1]=dis[id][0];
                cnt[id][1]=cnt[id][0];
                dis[id][0]=len1;
                cnt[id][0]=cnt[rt][tem.t];
                q.push(point(id,dis[id][1],1));
                q.push(point(id,dis[id][0],0));
            }else if(len1==dis[id][1])
            {
                cnt[id][1]+=cnt[rt][tem.t];
            }else if(len1<dis[id][1])
            {
                dis[id][1]=len1;
                cnt[id][1]=cnt[rt][tem.t];
                q.push(point(id,dis[id][1],1));
            }
        }
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        len=0;
        ms(first,-1);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            //add(y,x,z);
        }
        int s,f;
        scanf("%d%d",&s,&f);
        dij(s);
        int ans=cnt[f][0]+(dis[f][1]==dis[f][0]+1?cnt[f][1]:0);
        printf("%d\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/daydreamer23333/article/details/107498383