【最短路】Newyear

重庆城里有n个车站,m条双向公路连接其中的某些车站。每两个车站最多用一条公路连接,从任何一个车站出发都可以经过一条或者多条公路到达其他车站,但不同的路径需要花费的时间可能不同。在一条路径上花费的时间等于路径上所有公路需要的时间之和。

佳佳的家在车站1,他有五个亲戚,分别住在车站a,b,c,d,e。过年了,他需要从自己的家出发,拜访每个亲戚(顺序任意),给他们送去节日的祝福。怎样走,才需要最少的时间?

输入

第一行:n(n<=50,000),m(m<=100,000)为车站数目和公路的数目。

第二行:a,b,c,d,e,为五个亲戚所在车站编号(1<a,b,c,d,e<=n)。

以下m行,每行三个整数x,y,t(1<=x,y<=n,1<=t<=100),为公路连接的两个车站编号和时间。

输出

 仅一行,包含一个整数T,为最少的总时间

样例输入

6  6

2  3  4  5  6

1  2  8

2  3  3

3  4  4

4  5  5

5  6  2

1  6  7

样例输出

21

【问题分析】

简单的最短路,每个点一遍SPFA就好啦

【解决问题】

点1以及abcde五个点一次SPFA计算出六个点间任意两点最短路+搜索

Tips:算了算时间复杂度在本机上测最后三个大的点是超时,然而,然而,然而,评测机上居然A了!……恩,肯定是我家电脑太慢了。当然,读入优化也是必要的。

【代码实现】

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

const int A=50010,B=100000*2+10,inf=4e8;
int n,m,sum,ans=inf,s;
int x,y,z;
int head[A],g[8][8],l[8]={1},dis[6][A],ex[6][A],bo[A];
int line[A],ss;
struct edge{
    int to,nxt,len;
}e[B];
queue<int>q;

void build(int from,int to,int len)
{
    e[++sum].to=to;
    e[sum].nxt=head[from];
    e[sum].len=len;
    head[from]=sum;
}

void SPFA(int t,int st)
{
    for(int i=1;i<=n;++i)dis[t][i]=inf;
    dis[t][st]=0;
    q.push(st);
    while(!q.empty())
    {
        int tmp=q.front();
        q.pop();
        ex[t][tmp]=0;
        for(int i=head[tmp];i;i=e[i].nxt)
        {
            if(e[i].len+dis[t][tmp]<dis[t][e[i].to])
            {
                dis[t][e[i].to]=e[i].len+dis[t][tmp];
                if(!ex[t][e[i].to])
                {
                    ex[t][e[i].to]=1;
                    q.push(e[i].to);
                }
            }
        }
    }
    for(int i=t+1;i<=5;++i)
        g[t][i]=g[i][t]=dis[t][l[i]];
}

bool check()
{
    for(int i=1;i<=5;++i)
        if(!bo[i])return false;
    return true;
}

void search(int x)
{
    for(int i=1;i<=5;++i)
    {
        if(!bo[i])
        {
            bo[i]=1;
            s+=g[x][i];
            if(check())
            {
                if(s<ans)ans=s;
            }
            else
            search(i);
            bo[i]=0;
            s-=g[x][i];
        }
    }
}

void read(int &x)
{
    x=0;
    char ch=getchar();
    while(ch>‘9‘||ch<‘0‘)ch=getchar();
    while(ch>=‘0‘&&ch<=‘9‘)
    {
        x=x*10+ch-‘0‘;
        ch=getchar();
    }
}

int main()
{
    read(n);
    read(m);
    for(int i=1;i<=5;++i)read(l[i]);
    for(int i=1;i<=m;++i)
    {
        read(x);
        read(y);
        read(z);
        build(x,y,z);
        build(y,x,z);
    }
    for(int i=0;i<=5;++i)
        SPFA(i,l[i]);
    ans=inf;
    s=0;
    search(0);
    printf("%d\n",ans);
    return 0;
}
时间: 2024-08-06 08:11:15

【最短路】Newyear的相关文章

CJOI 05新年好 (最短路+枚举)

CJOI 05新年好 (最短路+枚举) 重庆城里有n个车站,m条双向公路连接其中的某些车站.每两个车站最多用一条公路连接,从任何一个车站出发都可以经过一条或者多条公路到达其他车站,但不同的路径需要花费的时间可能不同.在一条路径上花费的时间等于路径上所有公路需要的时间之和. 佳佳的家在车站1,他有五个亲戚,分别住在车站a,b,c,d,e.过年了,他需要从自己的家出发,拜访每个亲戚(顺序任意),给他们送去节日的祝福.怎样走,才需要最少的时间? 输入 第一行:n(n<=50,000),m(m<=10

hdu3461Marriage Match IV 最短路+最大流

//给一个图.给定起点和终点,仅仅能走图上的最短路 //问最多有多少种走的方法.每条路仅仅能走一次 //仅仅要将在最短路上的全部边的权值改为1.求一个最大流即可 #include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<vector> using namespace std ; const int inf = 0x3f3f3f3f ; const

UESTC30-最短路-Floyd最短路、spfa+链式前向星建图

最短路 Time Limit: 3000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的T-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据. 每组数据第一行是两个整数NN ,MM (N≤100N≤100 ,M≤10000M≤1000

ACM: HDU 2544 最短路-Dijkstra算法

HDU 2544最短路 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线,你可以帮助他们吗? Input 输入包括多组数据.每组数据第一行是两个整数N.M(N<=100,M<

ACM/ICPC 之 昂贵的聘礼-最短路解法(POJ1062)

//转移为最短路问题,枚举必经每一个不小于酋长等级的人的最短路 //Time:16Ms Memory:208K #include<iostream> #include<cstring> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; #define INF 0x3f3f3f3f #define MAX 105 int lim, n; int p[M

图论(A*算法,K短路) :POJ 2449 Remmarguts&#39; Date

Remmarguts' Date Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 25216   Accepted: 6882 Description "Good man never makes girls wait or breaks an appointment!" said the mandarin duck father. Softly touching his little ducks' head, h

hdu4725 拆点+最短路

题意:有 n 个点,每个点有它所在的层数,最多有 n 层,相邻两层之间的点可以互相到达,消耗 c (但同一层并不能直接到达),然后还有一些额外的路径,可以在两点间互相到达,并且消耗一定费用.问 1 点到 n 点的最小花费 将每一层拆成两个点,分别为进入层和出发层,然后相邻层的出发层可以指向进入层,花费 c,每个点可以到达其出发层,而进入层可以到达该点,花费 0 ,最后建立其余双向边,最短路 1 #include<stdio.h> 2 #include<string.h> 3 #in

hdu3416 最短路+最大流

题意:有 n 点 m 边,有出发点 A 到达点 B ,只允许走原图中的最短路,但每条边只允许被走一次,问最多能找出多少条边不重复的最短路 一开始做到的时候瞎做了一发最短路,WA了之后也知道显然不对,就放着了,后来打了今年的多校,再做到的时候发现和多校第一场的1007一样的……最短路+网络流就行了,只不过第一次做这个的时候我还不知道网络流是啥,不会做也正常啦. 首先对于原图跑一遍最短路求出每个点距离 A 点的最短路,然后对于每一条边,如果它的权值等于它连接的两点的最短路的差值的时候,就说明这条路是

【啊哈!算法】算法7:Dijkstra最短路算法

上周我们介绍了神奇的只有五行的Floyd最短路算法,它可以方便的求得任意两点的最短路径,这称为“多源最短路”.本周来来介绍指定一个点(源点)到其余各个顶点的最短路径,也叫做“单源最短路径”.例如求下图中的1号顶点到2.3.4.5.6号顶点的最短路径. <ignore_js_op> 与Floyd-Warshall算法一样这里仍然使用二维数组e来存储顶点之间边的关系,初始值如下. <ignore_js_op> 我们还需要用一个一维数组dis来存储1号顶点到其余各个顶点的初始路程,如下.