关键词:二维最短路、dij+heap、spfa
题意:已知起点和终点为s和t,还已知一个集合内含有若干三元组(a,b,c).求不能连续经过a->b->c,从s到t的最短路径
解法:设d[u][v]:从s出发,到达“前继是u,当前节点是v”状态的最短路径
然后用spfa或dij+heap优化求解二维最短路径即可
松弛条件:
ma[MP(pre,u)].find(v)==ma[MP(pre,u)].end()&&d[u][v]>d[pre][u]+w
三元组用mapint ,int>,set<int> >存储
可以通过前继pre和当前节点u找到下一个v,使得(pre,u,v)在三元组中的节点
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mem(a,b) memset(a,sizeof(a),b)
#define ll long long
#define INF 0x3f3f3f3f
#define MP make_pair
using namespace std;
const int maxn = 3000+10;
int n,m,k;
vector<int> g[maxn][2];
mapint ,int>, set<int> > ma;
int d[maxn][maxn],fa[maxn][maxn];//d[u][v]从起点到达状态“前继是u,当前点是v”的最短路径
bool inq[maxn][maxn];
int cnt[maxn][maxn];
//bool vis[maxn][maxn];
int npre,ans;
void add(int u,int v,int w){
g[u][0].push_back(v),g[u][1].push_back(w);
}
struct Heapnode{
int pre,u,d;
bool operator<(const Heapnode&rhs)const{
return d>rhs.d;
}
};
//法一:dij+heap优化
/*void dij(int s,int t){
priority_queue q;
memset(vis,0,sizeof(vis));
memset(fa,-1,sizeof(fa));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=INF;
d[0][1]=0;
q.push((Heapnode){0,1,d[0][1]});
while(!q.empty()){
Heapnode x=q.top();q.pop();
int pre=x.pre,u=x.u;
if(vis[pre][u]) continue;
vis[pre][u]=1;
for(int i=0;id[pre][u]+w){
d[u][v]=d[pre][u]+w;
fa[u][v]=pre;
q.push((Heapnode){u,v,d[u][v]});
}
}
}
}*/
//法二:spfa
void spfa(int s,int t){
queue q;
memset(inq,0,sizeof(inq));
memset(cnt,0,sizeof(cnt));
memset(fa,-1,sizeof(fa));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
d[i][j]=INF;
d[0][1]=0,inq[0][1]=1;
q.push((Heapnode){0,1,d[0][1]});
while(!q.empty()){
Heapnode x=q.front();q.pop();
int pre=x.pre,u=x.u;
inq[pre][u]=0;
for(int i=0;i0].size();i++){
int v=g[u][0][i],w=g[u][1][i];
if(ma[MP(pre,u)].find(v)==ma[MP(pre,u)].end()&&d[u][v]>d[pre][u]+w){
d[u][v]=d[pre][u]+w;
fa[u][v]=pre;
q.push((Heapnode){u,v,d[u][v]});
inq[u][v]=1;
if(++cnt[u][v]>n) return ;
}
}
}
}
void print(int pre,int u){
if(u==1) { printf("%d",u); return; }
print(fa[pre][u],pre);
printf(" %d",u);
}
int main(){
//freopen("a.txt","r",stdin);
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++) { g[i][0].clear(); g[i][1].clear(); }
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d",&a,&b);
add(a,b,1),add(b,a,1);
}
ma.clear();
for(int i=1;i<=k;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
ma[MP(a,b)].insert(c);
}
//dij(1,n);法一
spfa(1,n);//法二
npre=-1,ans=INF;
for(int i=1;iif(d[i][n]if(ans!=INF){
printf("%d\n",ans);
print(npre,n);
printf("\n");
}
else printf("-1\n");
}