hdu 4725 The Shortest Path in Nya Graph(最短路+虚点)

题目链接:(http://acm.hdu.edu.cn/showproblem.php?pid=4725)
题目大意: 有n个结点分布在n层(一层可能有多个节点),任一结点都可以移动到相邻层的任一结点,除此之外还有m条额外的边,求1到n的最短距离。(0<=n,m<=105

思路: 除了数据有点大之外就是一个常规的最短路问题,主要就是相邻层之间的存边。看了博客才发现给每层建一个层结点就解决了边太多的问题,最开始就想到了同一层之间移动的“花费为0”,但是建边的过程中发现保证不了同一层之间不能直接到达的事实……

层结点的作用是这样实现的:
比如,现在有两层的结点,假设每层有n个结点,m是第一层的结点,p是第二层的结点
第一层:M m1,m2,m3,m4,m5,m6……mn
第二层:P p1, p2, p3, p4, p5, p6……pn

如果暴力存的话,每一点都可以移动到相邻层,还是双向的,就要存2n2条边
现在我们建一个层结点M,在第一层中建n条M——>mi的单向边,花费为0(保证花费相同),这样的话,如果一个结点能到点M,就相当于它能到第一层的所有点。所以在前面n条边的基础上,如果表示p1到第一层的点就只需要建一条边p1——>M,,,,,,,,所以这样的话表示这两层之间的关系就只需要建2*2n=4n条边

建边(邻接表的spfa):
//代码中第i层的层结点使用n+i表示的

struct node
{
    int e,len,bf;
} edge[manx<<3];
void add(int s,int n,int len)
{
    edge[cou]=node{n,len,head[s]};
    head[s]=cou++;
}
int main()
{
    int t,u,v,w,pos;
    scanf("%d",&t);
    for(int k=1; k<=t; k++)
    {
        scanf("%d%d%d",&n,&m,&c1);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&pos);
            add(pos+n,i,0);//单向边
            if(pos!=1)
                add(i,pos+n-1,c1);//点i到相邻两层的层结点的单向边
            if(pos!=n)
                add(i,pos+n+1,c1);

        }
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
    }
}

然后就是最短路的模板了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值