CCF 201712-4 行车路线

思路:用两个数组维护到达某个点的最小大路距离和最小小路距离,注意结果中间过程可能爆int, 不加long long 只有70分。
有一种特殊情况就是通过走两次大路,消除连续的小路值,这里就是用两个数组维护的原因。
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
typedef long long LL;
int n,m;
struct Edge
{
    int to,from, t;
    LL w;
} edge[2*MAXN];
struct node
{
    int u;
    LL d1,d2;
};
LL dist1[MAXN],dist2[MAXN];
int head[2*MAXN];
int cnt;
void add(int t, int u, int v, LL w)
{
    edge[cnt].to=v;
    edge[cnt].w=w;
    edge[cnt].t=t;
    edge[cnt].from=head[u];
    head[u]=cnt++;
}
void spfa(int s)
{
    queue<node> q;
    while(!q.empty())
        q.pop();
    memset(dist1,-1,sizeof(dist1));
    memset(dist2,-1,sizeof(dist2));
    dist1[1]=dist2[1]=0;
    q.push((node)
    {
        s,0,0
    });
    while(!q.empty())
    {
        node u=q.front();
        q.pop();
        for(int i=head[u.u]; ~i; i=edge[i].from)
        {
            Edge v=edge[i];
            if(v.t==0)
            {
                if(dist1[v.to]==-1||dist1[v.to]>=u.d1+v.w+u.d2*u.d2)
                {
                    dist1[v.to]=u.d1+v.w+u.d2*u.d2;
                    q.push((node)
                    {
                        v.to,u.d1+v.w+u.d2*u.d2,0
                    });
                }
            }
            else
            {
                if(dist2[v.to]==-1||dist2[v.to]>=u.d1+(v.w+u.d2)*(v.w+u.d2))
                {
                    dist2[v.to]=u.d1+(v.w+u.d2)*(v.w+u.d2);
                    q.push((node)
                    {
                        v.to,u.d1,u.d2+v.w
                    });
                }
            }
        }
    }
    //for(int i=1; i<=n; ++i)
        //printf("%d dist1[%d]=%d dist2[%d]=%d\n", i, i, dist1[i], i, dist2[i]);
    if(dist1[n]==-1)
        printf("%lld\n", dist2[n]);
    else if(dist2[n]==-1)
        printf("%lld\n", dist1[n]);
    else
        printf("%lld\n", min(dist1[n],dist2[n]));
}

int main()
{
    cnt=0;
    memset(head,-1,sizeof(head));
    scanf("%d %d", &n,&m);
    for(int i=1; i<=m; ++i)
    {
        int t, a, b;
        LL c;
        scanf("%d %d %d %lld", &t, &a, &b, &c);
        add(t,a,b,c);
        add(t,b,a,c);
    }
    spfa(1);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/fanhansheng/article/details/79044347
今日推荐