spfa+dp;
显然,最短路上的公共路径一定是连续的。这道题我一开始too young too simple 地进行了暴力dp,结果T了。。。。。。
55分code:
// luogu-judger-enable-o2
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
#include<algorithm>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
typedef pair<int,int>p;
const int maxn=4000006;
int x1,x2,y1,y2;
struct hzw
{
int to,next,v;
}e[maxn];
int head[maxn],cur,dis[1501][1501],n,m,k;
inline void add(int a,int b,int c)
{
e[cur].to=b;
e[cur].next=head[a];
e[cur].v=c;
head[a]=cur++;
}
inline void dij(int shit)
{
priority_queue<p,vector<p>,greater<p> >q;
dis[shit][shit]=0;
q.push(p(0,shit));
while (!q.empty())
{
p now=q.top();
q.pop();
int s=now.second;
if (dis[shit][s]< now.first) continue;
for (int i=head[s];i!=-1;i=e[i].next)
{
if (dis[shit][e[i].to]>dis[shit][s]+e[i].v)
{
dis[shit][e[i].to]=dis[shit][s]+e[i].v;
q.push(p(dis[shit][e[i].to],e[i].to));
}
}
}
}
bool cmp(int x,int y)
{
return x>y;
}
signed main()
{
memset(head,-1,sizeof(head));
cin>>n>>m;
cin>>x1>>x2>>y1>>y2;
for (int i=1,a,b,c;i<=m;++i)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
add(b,a,c);
}
memset(dis,0x3f,sizeof(dis));
for (int i=1;i<=n;++i)
{
dij(i);
}
int ans=0;
for (int i=1;i<=n;++i)
{
for (int j=1;j<=n;++j)
{
if ((dis[x1][i]+dis[i][j]+dis[j][x2]==dis[x1][x2] || dis[x1][j]+dis[j][i]+dis[i][x2]==dis[x1][x2])&&(dis[y1][i]+dis[i][j]+dis[j][y2]==dis[y1][y2] || dis[y1][j]+dis[j][i]+dis[i][y2]==dis[y1][y2]))
{
ans=max(ans,dis[i][j]);
}
}
}
cout<<ans;
return 0;
}
100pts:
我们考虑55分的代码浪费在了什么地方:判定太慢了!考虑优化:我们可以跑4遍最短路,对于一条路径u—v,如果dis(s,i)+len(i,j)+dis(j,t)=dis(s,t),我们就认为这是一条合法的道路。标记一下。同理,我们将主角的cp也处理一下,这样,我们就得到了一条由合法路径组成的图了,dp找最长链就好了。