hrbust 1669 回家Ⅱ【二维最短路】

回家

Time Limit: 1000 MS

Memory Limit: 32768 K

 

Total Submit: 34(7 users)

Total Accepted: 7(5 users)

Rating: 

Special Judge: No

 

Description

    lz买了个新车,现在他想开着车回到家里,但是回家的道路没有直达的,所以他必须经过一些城市。

    一开始,车上只有他自己一个人(lz从编号为1的城市出发),车的行驶速度为每单位距离花费1单位的时间,但是当车上有x个人的时候,每单位的距离将花费x单位的时间。每座城市都住着lz的一个朋友,每次经过一个城市的时候,就会有一个朋友坐上车和lz一起回到家中(出发的城市不会有朋友上车),但是lz想早点回到家(编号为n的城市),请帮助lz计算出回到家最少要花多少时间。

Input

多组测试数据。

每组测试数据第一行输入两个正整数 n , m (0 < n ≤ 200, 0 < m < n×(n-1)/2 ), n 代表城市的数量,m表示现有道路的数量。

接下来的m行,每行输入三个整数x,y,z表示x,y城市之间有一条长度为z个单位距离的双向道路。

Output

对于每组数据输出一个整数表示lz回到家的最少时间,每组输出占一行。

Sample Input

3 2
1  2 1
2 3 2
5 6
1 2 1
1 4 5
2 3 2
3 5 1
4 5 1
2 4 2

 

Sample Output

5
7

 

Author

`Wind @hrbust

 

思路:


1、首先想到裸SPFA,样例过掉了,但是仔细YY了一下,判vis【】的时候,会误判当前情况的入队于否,然后找了两组样例,果然对不上。


2、既然一维判重过不掉,那我们就二维判重,令误判了的入队于否的情况,使其变得正确了就好辣!


3、以后有限制的最短路,再也不敢用一维判重辣T T !!!以后有限制的最短路,再也不敢直接开一维dis【】辣!!!

AC代码:


#include<stdio.h>
#include<queue>
#include<string.h>
using namespace std;
struct node
{
    int u,cur;
}now,nex;
struct EdgeNode
{
    int to;
    int w;
    int next;
}e[1000000];
int head[210];
int vis[210][5000];
int ansdis[210];
int dis[210][5000];
int n,m,cont;
void add(int from,int to,int w)
{
    e[cont].to=to;
    e[cont].w=w;
    e[cont].next=head[from];
    head[from]=cont++;
}
void SPFA(int ss)
{
    for(int i=1;i<=n;i++)ansdis[i]=0x3f3f3f3f;
    memset(dis,0x3f3f3f3f,sizeof(dis));
    memset(vis,0,sizeof(vis));
    queue<node >s;
    now.cur=1;
    now.u=ss;
    s.push(now);
    vis[now.u][1]=1;
    dis[now.u][1]=0;
    ansdis[now.u]=0;
    while(!s.empty())
    {
        now=s.front();
        s.pop();
        vis[now.u][now.cur]=0;
        int u=now.u;
        int cur=now.cur;
        for(int j=head[u];j!=-1;j=e[j].next)
        {
            int v=e[j].to;
            int w=e[j].w;
            if(ansdis[v]>dis[u][cur]+w*cur)
            {
                dis[v][cur+1]=dis[u][cur]+w*cur;
                ansdis[v]=dis[v][cur+1];
                if(vis[v][cur+1]==0)
                {
                    nex.u=v;
                    nex.cur=now.cur+1;
                    s.push(nex);
                    vis[v][cur+1]=1;
                }
            }
        }
    }
    printf("%d\n",ansdis[n]);
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        cont=0;
        memset(head,-1,sizeof(head));
        for(int i=0;i<m;i++)
        {
            int x,y,w;
            scanf("%d%d%d",&x,&y,&w);
            add(x,y,w);
            add(y,x,w);
        }
        SPFA(1);
    }
}
/*
8 10
1 2 2
2 5 4
1 3 1
3 5 4
3 6 1
6 5 1
5 7 4
5 4 1
4 8 2
7 8 1
*/






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值