【SDOI2009】Elaxia的路線(拓撲+最短路+dp)
阿新 • • 發佈:2018-12-30
先找出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; }