HDU 3499【最短路】

题意:
给你一幅图,然后起点终点,然后有一个条件是可以使某条边的花费减半,求最短路的最小花费。
思路:
(来自大哥)
最短路的时候多一维,途中是否有花费减半的边;
然后转移,如果上一条有减半的,这一条一定只能转移到不能减半,上一条没有减半的,这一条可以减半也可以不减半。
具体处理就是一个二维的处理,网上说分层图,其实我感觉就是DP的思想,还有有一种从一张图跑到另一张图的feel。
后来wa了,就是挫在初始化,还有数据要LL,哎,艹!;
贴一发自己的挫code…

#include<cstdio>
#include<iostream>
#include<queue>
#include<string.h>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
#define LL long long

const int N=5e5+10;

struct asd{
    int to;
    LL w;
    int next;
};
asd q[N*4];
int head[N*4],tol;
int n,m;

map<string,int>mp;
int tot;

int Getpoint(string ss)
{
    if(mp.find(ss)!=mp.end())
        return mp[ss];
    return mp[ss]=++tot;
}

void init()
{
    memset(head,-1,sizeof(head));
    mp.clear();
    tol=0;
    tot=0;
}

void add(int a,int b,int c)
{
    q[tol].to=b;
    q[tol].w=c;
    q[tol].next=head[a];
    head[a]=tol++;
}

typedef pair<int,int> PP;
queue<PP>que;

const int M=1e5+10;
const long long INF=1e15;
LL dis[N][2];
bool vis[N][2];
int num[N][2];
LL spfa(int s,int t)
{
    while(!que.empty())
        que.pop();
    for(int i=1;i<=n;i++)
    {
        dis[i][0]=INF;
        dis[i][1]=INF;
        vis[i][0]=false;
        vis[i][1]=false;
        num[i][0]=0;
        num[i][1]=0;
    }
    dis[s][0]=dis[s][1]=0;
    num[s][0]=num[s][1]=1;
    vis[s][0]=vis[s][1]=true;
    que.push(make_pair(s,0));
    que.push(make_pair(s,1));
    while(!que.empty())
    {
        PP u=que.front();
        que.pop();
        vis[u.first][u.second]=0;
        for(int v=head[u.first];v!=-1;v=q[v].next)
        {
            int i=q[v].to;
            if(u.second==1)
            {
                if(dis[i][1]>dis[u.first][u.second]+q[v].w)
                {
                    dis[i][1]=dis[u.first][u.second]+q[v].w;
                    if(!vis[i][1])
                    {
                        vis[i][1]=1;
                        num[i][1]++;
                        if(num[i][1]>=tot)
                            return -1;
                        que.push(make_pair(i,1));
                    }
                }
            }
            else
            {
                if(dis[i][0]>dis[u.first][u.second]+q[v].w)
                {
                    dis[i][0]=dis[u.first][u.second]+q[v].w;
                    if(!vis[i][0])
                    {
                        vis[i][0]=1;
                        num[i][0]++;
                        if(num[i][0]>=tot)
                            return -1;
                        que.push(make_pair(i,0));
                    }
                }
                if(dis[i][1]>dis[u.first][u.second]+q[v].w/2)
                {
                    dis[i][1]=dis[u.first][u.second]+q[v].w/2;
                    if(!vis[i][1])
                    {
                        vis[i][1]=1;
                        num[i][1]++;
                        if(num[i][1]>=tot)
                            return -1;
                        que.push(make_pair(i,1));
                    }
                }
            }
        }
    }
    if(dis[t][1]==INF)
        return -1;
    return dis[t][1];
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        string x,y;
        int w;
        init();
        for(int i=0;i<m;i++)
        {
            cin>>x>>y>>w;
            int xx=Getpoint(x);
            int yy=Getpoint(y);
            //printf("%d %d
",xx,yy);
            add(xx,yy,w);
        }
        cin>>x>>y;
        if(mp.find(x)==mp.end()||mp.find(y)==mp.end())
        {
            puts("-1");
            continue;
        }
        int s=Getpoint(x);
        int t=Getpoint(y);
        //printf("%d %d
",s,t);
        printf("%lld
",spfa(s,t));
    }
    return 0;
}
原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934773.html