1.Question:
题意:
输入第一行n,m,t三个数代表的含义分别是图中的n个点,m条有向边,t为初始定点
之后的m行代表我们图中的m条有向边
在题目要求从t初始点到所有的点点额单源最短路径和将所有的有向边反向之后,我们再求一次单源最短路径
求两次的最短路径之和的最大值
2.Solution:
单元最短路径问题
本题因为牵扯到有向边的反向问题,所以我们最好选用矩阵的数据结构来进行存储
题中的要求设计到矩阵的转置
之后就是SPFA或者Dijkstra的模板
3.Code:
SPFA
/*
Source Code
Problem: 3268
User: lantianheyeqi
Memory: 4504K
Time: 32MS
Language: C++
Result: Accepted
*/
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdlib"
#define N 1005
#define INF 0X7fffffff
using namespace std;
int n,m,t;
int dis[2][N];
int map[N][N];
bool book[N];
void SPFA(int atom)
{
memset(book,0,sizeof(book));
int queue[N*100];
int head=1;
int tail=2;
queue[1]=t;
book[t]=1;
for(int i=1;i<=n;i++) dis[atom][i]=INF;
dis[atom][t]=0;
while(head!=tail)
{
for(int i=1;i<=n;i++)
{
if(map[queue[head]][i]!=INF&&dis[atom][i]>dis[atom][queue[head]]+map[queue[head]][i])
{
dis[atom][i]=dis[atom][queue[head]]+map[queue[head]][i];
if(book[i]==0)
{
book[i]=1;
queue[tail++]=i;
}
}
}
book[queue[head]]=0;
head++;
}
}
int main()
{
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=INF;
}
}
for(int i=1;i<=m;i++)
{
int dx,dy,dz;
scanf("%d%d%d",&dx,&dy,&dz);
map[dx][dy]=dz;
}
SPFA(0);
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
int t=map[i][j];
map[i][j]=map[j][i];
map[j][i]=t;
}
}
SPFA(1);
int mink=-1;
for(int i=1;i<=n;i++)
{
dis[0][i]+=dis[1][i];
if(mink<dis[0][i]) mink=dis[0][i];
}
printf("%d\n",mink);
return 0;
}
Dijstra
/*
Problem: 3268
User: lantianheyeqi
Memory: 4116K
Time: 79MS
Language: C++
Result: Accepted
*/
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cstdlib"
#define N 1005
#define INF 0x7fffffff
using namespace std;
int map[N][N];
int n,m,t;
int dis[2][N];
bool book[N];
void dijstra(int atom)
{
memset(book,0,sizeof(book));
book[t]=1;
for(int i=1;i<=n;i++) dis[atom][i]=map[t][i];
dis[atom][t]=0;
for(int i=1;i<=n-1;i++)
{
int mink=INF;
int minpoint;
for(int j=1;j<=n;j++)
{
if(book[j]==0&&dis[atom][j]<mink)
{
mink=dis[atom][j];
minpoint=j;
}
}
book[minpoint]=1;
for(int j=1;j<=n;j++)
{
if(book[j]==0&&map[minpoint][j]!=INF&&dis[atom][j]>dis[atom][minpoint]+map[minpoint][j])
{
dis[atom][j]=dis[atom][minpoint]+map[minpoint][j];
}
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++) map[i][j]=INF;
}
for(int i=1;i<=m;i++)
{
int dx,dy,dz;
scanf("%d%d%d",&dx,&dy,&dz);
map[dx][dy]=dz;
}
dijstra(0);
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
{
int t=map[i][j];
map[i][j]=map[j][i];
map[j][i]=t;
}
}
dijstra(1);
int mink=-1;
for(int i=1;i<=n;i++)
{
dis[0][i]+=dis[1][i];
if(mink<dis[0][i]) mink=dis[0][i];
}
printf("%d\n",mink);
return 0;
}