「CODEVS1021」玛丽卡
题目描述 Description
麦克找了个新女朋友,玛丽卡对他非常恼火并伺机报复。
因为她和他们不住在同一个城市,因此她开始准备她的长途旅行。
在这个国家中每两个城市之间最多只有一条路相通,并且我们知道从一个城市到另一个城市路上所需花费的时间。
麦克在车中无意中听到有一条路正在维修,并且那儿正堵车,但没听清楚到底是哪一条路。无论哪一条路正在维修,从玛丽卡所在的城市都能到达麦克所在的城市。
玛丽卡将只从不堵车的路上通过,并且她将按最短路线行车。麦克希望知道在最糟糕的情况下玛丽卡到达他所在的城市需要多长时间,这样他就能保证他的女朋友离开该城市足够远。
编写程序,帮助麦克找出玛丽卡按最短路线通过不堵车道路到达他所在城市所需的最长时间(用分钟表示)。
输入描述 Input Description
第一行有两个用空格隔开的数N和M,分别表示城市的数量以及城市间道路的数量。1≤N≤1000,1≤M≤N*(N-1)/2。城市用数字1至N标识,麦克在城市1中,玛丽卡在城市N中。
接下来的M行中每行包含三个用空格隔开的数A,B和V。其中1≤A,B≤N,1≤V≤1000。这些数字表示在A和城市B中间有一条双行道,并且在V分钟内是就能通过。
输出描述 Output Description
输出文件的第一行中写出用分钟表示的最长时间,在这段时间中,无论哪条路在堵车,玛丽卡应该能够到达麦克处,如果少于这个时间的话,则必定存在一条路,该条路一旦堵车,玛丽卡就不能够赶到麦克处。
样例输入 Sample Input
5 7
1 2 8
1 4 10
2 3 9
2 4 10
2 5 1
3 4 7
3 5 10
样例输出 Sample Output
27
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
#include<cstdio> #include<iostream> #include<cstring> using namespace std; struct data{ int from,to,next,v; }e[1000001]; int n,m,ans; int ne; int head[1001]; bool inq[1001],del[1000001]; int q[1000001],dis[1001],father[1001]; void insert(int u,int v,int w) { ne++; e[ne].from=u; e[ne].to=v; e[ne].v=w; e[ne].next=head[u]; head[u]=ne; } void spfa(int k) { memset(dis,127,sizeof(dis)); memset(inq,0,sizeof(inq)); int t=0,w=1,now; q[t]=1;inq[1]=1;dis[1]=0; while(t<w) { int p=head[q[t]]; now=q[t];t++; while(p) { if(!del[p]&&dis[now]+e[p].v<dis[e[p].to]) { dis[e[p].to]=dis[now]+e[p].v; if(k==1)father[e[p].to]=p; if(!inq[e[p].to]) { inq[e[p].to]=1; q[w++]=e[p].to; } } p=e[p].next; } inq[now]=0; } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); insert(x,y,z);insert(y,x,z); } spfa(1); ans=dis[n]; for(int i=n;i!=1;i=e[father[i]].from) { del[father[i]]=1;spfa(0);del[father[i]]=0; ans=max(dis[n],ans); } printf("%d",ans); return 0; } |
黄学长收下我的洛阳铲!
这个数据生成出来您好像跑了30s+
#include
int n=1000;
int m=n*(n-1)/2;
int main()
{
printf(“%d %d\n”,n,m);
for(int i=1;i<n;i++)
{
printf("%d %d 1\n",i,i+1);
for(int j=i+2;j<=n;j++)
printf("%d %d 1000\n",i,j);
}
}
万能的黄学长啊…
这题nm的复杂度不会GG吗…
你怎么删除的双向边
完全不记得了