时间限制 1000 ms 内存限制 65536 KB
题目描述
计算从城市1到城市n的最短路径长度。分为白天和黑夜,黑夜会关掉若干条线路,分别计算城市1到城市n的在白天和黑夜的最短路径长度。保证每个城市与其他城市必有连接。两个城市之间可能有多条路。
输入格式
第一行为数据组数T
对于每组测试数据
第一行三个整数,n,m,k. (1<=n<=50)n表示城市个数,m表示道路个数,k表示黑夜需要关闭的道路个数。
接下来m行,每行 三个整数 x,y,c (1<=x,y<=n),其中第 i 行(1<=i <=m)表示第 i 条道路为从城市x到城市y长度为c(可能存在重复边)。
接下来k行,每行一个整数w,表示黑夜要关闭的道路编号。
输出格式
每组数据输出两行
第一行为白天从城市1到城市n的最短距离
第二行为黑夜从城市1到城市n的最短距离
输入样例
2
4 4 1
1 2 1
2 3 1
3 4 1
1 4 1
4
4 5 1
1 2 1
2 3 2
3 4 3
1 3 1
1 4 7
4
输出样例
1
3
4
6
代码1://Floyed弗洛伊德实现,因为n<=50,O(n^3)不会超时
#include<bits/stdc++.h>
using namespace std;
struct B
{
int x,y,c;
}b[1003];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,k,i,j,w,x,y,c;
int d1[53][53],d2[53][53];
memset(d1,-1,sizeof(d1));//最大值用-1表示 若用0x7f表示 可能与另一个整数相加超出int的最大值 得到负值 则导致出错
memset(d2,-1,sizeof(d2));//或是存储路径用long long数组 然后用memset(d,0x7f,sizeof(d));初始化
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=m;++i)
{
scanf("%d%d%d",&x,&y,&c);
b[i].x=x;
b[i].y=y;
b[i].c=c;
if(d1[x][y]==-1)
{
d1[x][y]=d1[y][x]=c;
}
else if(d1[x][y]>c)
{
d1[y][x]=d1[x][y]=c;
}
}
for(i=0;i<k;++i)
{
scanf("%d",&w);
b[w].x=b[w].y=b[w].c=-1;
}
for(i=1;i<=m;++i)
{
if(b[i].x!=-1)
{
x=b[i].x;
y=b[i].y;
c=b[i].c;
if(d2[x][y]==-1)
{
d2[x][y]=d2[y][x]=c;
}
else if(d2[x][y]>c)
{
d2[x][y]=d2[y][x]=c;
}
}
}
//Floyed弗洛伊德
for(int z=1;z<=n;++z)
{
for(i=1;i<=n;++i)
{
for(j=1;j<=n;++j)
{
if(d1[i][z]!=-1&&d1[z][j]!=-1)
{
if(d1[i][j]!=-1)
d1[i][j]=min(d1[i][j],d1[i][z]+d1[z][j]);
else d1[i][j]=d1[i][z]+d1[z][j];
}
if(d2[i][z]!=-1&&d2[z][j]!=-1)
{
if(d2[i][j]!=-1)
d2[i][j]=min(d2[i][j],d2[i][z]+d2[z][j]);
else d2[i][j]=d2[i][z]+d2[z][j];
}
}
}
}
printf("%d\n%d\n",d1[1][n],d2[1][n]);
}
}
代码2: //Dijkstra迪杰斯特拉
#include<bits/stdc++.h>
using namespace std;
struct B
{
int x,y;
long long c;
}b[1003];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m,k,i,j,w,x,y,z[53];
long long c,d1[53][53],d2[53][53],dis1[53],dis2[53];
memset(d1,0x7f,sizeof(d1));//最大值用-1表示 若用0x7f表示 可能与另一个整数相加超出int的最大值 得到负值 则导致出错
memset(d2,0x7f,sizeof(d2));//或是存储路径用long long数组 然后用memset(d,0x7f,sizeof(d));初始化
memset(dis1,0x7f,sizeof(dis1));
memset(dis2,0x7f,sizeof(dis2));
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=m;++i)
{
scanf("%d%d%lld",&x,&y,&c);
b[i].x=x;
b[i].y=y;
b[i].c=c;
d1[x][y]=d1[y][x]=min(c,d1[x][y]);
}
for(i=0;i<k;++i)
{
scanf("%d",&w);
b[w].x=b[w].y=b[w].c=-1;
}
for(i=1;i<=m;++i)
{
if(b[i].x!=-1)
{
x=b[i].x;
y=b[i].y;
c=b[i].c;
d2[x][y]=d2[y][x]=min(c,d2[x][y]);
}
}
//Dijkstra迪杰斯特拉
for(i=2;i<=n;++i)
{
dis1[i]=d1[1][i];
dis2[i]=d2[1][i];
}
memset(z,0,sizeof(z));
z[1]=1;
for(i=1;i<n;++i)
{
int mi=0x7fffffff,z1=-1;
for(j=2;j<=n;++j)
{
if(!z[j]&&dis1[j]<mi)
{
mi=dis1[j];
z1=j;
}
}
if(z1!=-1)
{
z[z1]=1;
dis1[z1]=mi;
if(z1==n)break;
for(j=2;j<=n;++j)
{
if(!z[j])
{
dis1[j]=min(dis1[j],mi+d1[z1][j]);
}
}
}
}
printf("%lld\n",dis1[n]);
memset(z,0,sizeof(z));
z[1]=1;
for(i=1;i<n;++i)
{
int mi=0x7fffffff,z2=-1;
for(j=2;j<=n;++j)
{
if(!z[j]&&dis2[j]<mi)
{
mi=dis2[j];
z2=j;
}
}
if(z2!=-1)
{
z[z2]=1;
dis2[z2]=mi;
if(z2==n)break;
for(j=2;j<=n;++j)
{
if(!z[j])
{
dis2[j]=min(dis2[j],mi+d2[z2][j]);
}
}
}
}
printf("%lld\n",dis2[n]);
}
}