【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;
}
posted @ 2018-11-01 20:48  Patrickpwq  阅读(204)  评论(0编辑  收藏  举报