1399. 坐船旅行
题目描述
NOIP有N个岛屿,编号为1…N,NOIP决定在岛屿之间发展船运网络。,
你在船运票务中心工作,很多人想花尽量少的钱从一个岛到另一个岛进行坐船旅行,他们每个人都报上自己的出发地和目的地,你的任务是告诉他最小花费。
但是在这个过程中船的航线不会一直不变,可能会在某个时候增加一些航线,这些新增加的航线显然对之前的询问没有作用,但对之后的询问就要考虑到这些航线了。
按照时间先后的顺序给你一个清单,里面包含询问以及增加航线的信息,写一个程序回答游客提出的问题。
输入
第1行:两个数 N(1<=N<=100) 和 k(1<=k<=5000),分别表示岛屿的数量以及清单的长度。
下面K行描述清单内容,有两种:
(1)格式为0 a b(1<=a<=n,1<=b<=n,a<>b)表示游客询问岛a到岛b的最小费用;
(2)1 a b e(1<=a,b<=n,a<>b,1<=e<=1000000)表示在a到b之间新增一条航线,费用为e,注意航线都是双向的。
一开始,没有任何航线,并且总的航线数不超过1000,两个岛之间可能有多条航线。
输出
对于每个询问输出对应的最小费用。
样例输入
样例输入1:
3 8
1 3 1 10
0 2 3
1 2 3 20
1 1 2 5
0 3 2
1 1 3 7
1 2 1 9
0 2 3
样例输入2:
5 16
1 1 2 343750
1 1 3 3343
1 1 4 347392
1 1 5 5497
1 2 3 123394
1 2 4 545492
1 2 5 458
1 3 4 343983
1 3 5 843468
1 4 5 15934
0 2 1
0 4 1
0 3 2
0 4 2
0 4 3
0 5 3
样例输出
样例输出1:
-1
15
12
样例输出2:
5955
21431
9298
16392
24774
8840
数据范围限制
提示
思路:
我们对于这么大的值,并且是最短路,那第一时间就想到了spfa。但是呢,题目说明对于每两个点之间可能会有多条路,如何去一条最短的呢?
其实我们只需用一个数组来记录以前的值,最后每想加路时,都需做一个比较,然后就解决了。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout);
using namespace std;
const int MAX=2147483647;
const int N=1e6;
struct node
{
int x,y,next,z;
} edge[10010];
int n,k,tot,hd[10010],q[10010],minn[10010],jl[110][110];
bool f[10010];
void add(int u,int v,int w)
{
if(jl[u][v]) edge[jl[u][v]].z=edge[jl[v][u]].z=min(edge[jl[u][v]].z,w);
else
{
edge[++tot].x=u;
edge[tot].y=v;
edge[tot].z=w;
edge[tot].next=hd[u];
hd[u]=tot;
jl[u][v]=tot;
}
}
void spfa(int s)
{
memset(minn,127/3,sizeof(minn));
f[s]=1,q[1]=s,minn[s]=0;
int head=0,tail=1;
while(head<=tail)
{
head++;
int tx=q[head];
for(int i=hd[tx];i;i=edge[i].next)
{
if(minn[edge[i].y]>minn[tx]+edge[i].z)
{
minn[edge[i].y]=minn[tx]+edge[i].z;
if(!f[edge[i].y])
f[edge[i].y]=1,q[++tail]=edge[i].y;
}
}
f[tx]=0;
}
}
int main()
{
//fre();
scanf("%d%d",&n,&k);
for(int i=1;i<=k;i++)
{
int k,u,v,w;
scanf("%d",&k);
if(k) scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);
else if(!k)
{
scanf("%d%d",&u,&v);
spfa(u);
if(minn[v]==707406378) printf("-1\n");
else printf("%d\n",minn[v]);
}
}
return 0;
}