【SDOI2009】Elaxia的路线(拓扑+最短路+dp)
先找出Elaxia的最短路 重新建图 在此图上我们再标记同时也是w**的最短路的边
显然这是一个DAG 可以做dp 设f[i]表示以i点结尾的最长公共连续和(公共路径一定是一条链) 则f[vis]=max(f[now],f[now]+e[u].val*e[u].flag)(flag表示是否也是w**的最短路)
为了使得没有后效性 需要在拓扑排序时做dp
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#define N 1505
#define INF 0x3f3f3f3f
using namespace std;
template <class T>
inline void read(T &x)
{
x=0;
static char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
}
int n,m,x1,y1,x2,y2;
struct Edge
{
int from,to,next,val,flag;
}edge[N*N],res[N*N];
int tot,first[N],cnt,head[N];
inline void addedge(int x,int y,int z)
{
tot++;
edge[tot].from=x; edge[tot].to=y; edge[tot].next=first[x]; edge[tot].val=z; first[x]=tot;
}
inline void Rebuild_Graph(int x,int y,int z)
{
cnt++;
res[cnt].from=x; res[cnt].to=y; res[cnt].next=head[x]; res[cnt].val=z; head[x]=cnt;
}
int dis[N][5];
bool visit[N];
typedef pair<int,int> Pair;
void dijkstra(int s,int f)
{
memset(visit,false,sizeof(visit));
priority_queue<Pair,vector<Pair>,greater<Pair> > heap;
heap.push(make_pair(0,s)); dis[s][f]=0;
while(!heap.empty())
{
int now=heap.top().second;
heap.pop();
if(visit[now]) continue;
visit[now]=true;
for(int u=first[now];u;u=edge[u].next)
{
int vis=edge[u].to;
if(dis[now][f]+edge[u].val<dis[vis][f])
{
dis[vis][f]=dis[now][f]+edge[u].val;
heap.push(make_pair(dis[vis][f],vis));
}
}
}
}
int in[N];
void rebuild()
{
for(int u=1;u<=tot;u++)
{
int x=edge[u].from; int y=edge[u].to;
if(dis[x][1]+edge[u].val+dis[y][2]==dis[y1][1])
{
Rebuild_Graph(x,y,edge[u].val); //重新建图(Elaxia的最短路)
if(dis[x][3]+edge[u].val+dis[y][4]==dis[y2][3]||dis[x][4]+edge[u].val+dis[y][3]==dis[y2][3])
res[cnt].flag=1;
in[y]++;
}
}
}
int f[N];
void Topo_sort()
{
queue <int> q;
q.push(x1);
while(!q.empty())
{
int now=q.front();
q.pop();
for(int u=head[now];u;u=res[u].next)
{
int vis=res[u].to;
in[vis]--;
f[vis]=max(f[vis],f[now]+res[u].val*res[u].flag);
if(!in[vis]) q.push(vis);
}
}
}
int main()
{
read(n),read(m);
read(x1),read(y1),read(x2),read(y2);
for(int i=1,x,y,z;i<=m;i++)
{
read(x),read(y),read(z);
addedge(x,y,z); addedge(y,x,z);
}
memset(dis,0x3f,sizeof(dis));
dijkstra(x1,1); dijkstra(y1,2); dijkstra(x2,3); dijkstra(y2,4);
rebuild(); Topo_sort();
cout<<f[y1];
return 0;
}
QQ40523591~欢迎一起学习交流~