先求出那些在公共最短路上的边,并规定方向,对于边<u,v>,d(x1,u)<d(x1,v)。
然后这些边就组成了一个有向无环图,现在要求的就是这个图上的最长链。
就用动态规划做。
CODE:
/*
AUTHOR: Su Jiao
DATE: 2010-7-26
DESCRIPTION:
山东2009年省选 Elaxia的路线
*/
#include <stdio.h>
#include <string.h>
const int MAXN=1500;
const int oo=0x7f7f7f7f;
int N,M;
int x1,y1,x2,y2;
int map[MAXN+2][MAXN+2];
int dx1[MAXN+2];
int dy1[MAXN+2];
int dx2[MAXN+2];
int dy2[MAXN+2];
bool graph[MAXN+2][MAXN+2];
bool on_graph[MAXN+2];
bool calced[MAXN+2];
int f[MAXN+2];
void dijkstra(int s,int d[MAXN+2])
{
bool visited[MAXN+2];
memset(visited,0,sizeof(visited));
memset(d,oo,sizeof(int)*(MAXN+2));
d[s]=0;
for (int i=0;i<N;i++)
{
int minu,dminu=oo;
for (int u=1;u<=N;u++)
if (!visited[u]&&d[u]<dminu)
dminu=d[minu=u];
visited[minu]=true;
for (int u=1;u<=N;u++)
if (!visited[u]&&d[u]>dminu+map[minu][u])
d[u]=dminu+map[minu][u];
}
}
int dp(int u)
{
if (calced[u]) return f[u];
else
{
calced[u]=true;
for (int v=1;v<=N;v++)
if (graph[u][v])
f[u]>?=map[u][v]+dp(v);
return f[u];
}
}
int main()
{
scanf(“%d%d%d%d%d%d”,&N,&M,&x1,&y1,&x2,&y2);
memset(map,oo,sizeof(map));
for (int i=0,u,v,l;i<M;i++)
scanf(“%d%d%d”,&u,&v,&l),
map[u][v]=map[v][u]=l;
for (int u=1;u<=N;u++) map[u][u]=0;
dijkstra(x1,dx1);
dijkstra(y1,dy1);
dijkstra(x2,dx2);
dijkstra(y2,dy2);
for (int u=1;u<=N;u++)
for (int v=1;v<=N;v++)
if (u!=v
&&dx1[u]+map[u][v]+dy1[v]==dx1[y1]
&&(dx2[u]+map[u][v]+dy2[v]==dx2[y2]
||dy2[u]+map[u][v]+dx2[v]==dx2[y2]))
on_graph[u]=on_graph[v]=graph[u][v]=true;
int answer=0;
for (int u=1;u<=N;u++)
if (dp(u)>answer) answer=dp(u);
printf(“%d\n”,answer);
}