https://vjudge.net/contest/365635#problem/B
建两层图,因为只能跑一条商业线,可以从正常点向虚拟点建一条单向边
For(i,1,m){
in(x);in(y);in(v);
push(x,y,v);
push(y,x,v);
push(x+n,y+n,v);
push(y+n,x+n,v);
}
in(k);
For(i,1,k){
in(x);in(y);in(v);
push(x,y+n,v);
push(y,x+n,v);
}
看这个建图过程就应该能明白。
if(d[t+n]<d[t]) 意味着走商业线更短
否则经济线更短
对于那个商业线的点,就是从大于n的点到小于等于n的点过度的时候,也就是从虚拟图跑到实图的那一条边
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <stack>
#include <cstring>
#define inf 2147483647
#define N 1000010
#define p(a) putchar(a)
#define For(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
int n,s,t,m,x,y,v,k,temp,cnt;
int d[N],f[N];
bool vis[N],flag;
deque<int>q;
stack<int>st;
struct node{
int n;
int v;
node *next;
}*e[50000];
void in(int &x){
int y=1;char c=getchar();x=0;
while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
x*=y;
}
void o(int x){
if(x<0){p('-');x=-x;}
if(x>9)o(x/10);
p(x%10+'0');
}
void push(int x,int y,int v){
node *p;
p=new node();
p->v=v;
p->n=y;
if(e[x]==0)
e[x]=p;
else{
p->next=e[x]->next;
e[x]->next=p;
}
}
void clear(){
memset(e,0,sizeof(e));
flag=0;
}
void spfa(){
For(i,0,2*n) d[i]=inf;
d[s]=0;f[s]=s;
q.push_back(s);
while(!q.empty()){
x=q.front();q.pop_front();
vis[x]=1;
for(node *i=e[x];i;i=i->next){
if(d[i->n]>d[x]+i->v){
d[i->n]=d[x]+i->v;
f[i->n]=x;
if(!vis[i->n]){
if(!q.empty()&&d[i->n]<=d[q.front()]) q.push_front(i->n);
else q.push_back(i->n);
}
}
}
vis[x]=0;
}
}
void print(){
if(d[t]<d[t+n]){
temp=t;
while(temp!=f[temp]){
st.push(temp);
temp=f[temp];
}
st.push(s);
while(!st.empty()){
o(st.top());
if(st.size()!=1) p(' ');
else p('\n');
st.pop();
}
puts("Ticket Not Used");
o(d[t]);p('\n');
}
else{
temp=t+n;
while(temp!=f[temp]){
if(temp>n) st.push(temp-n);
else{
st.push(temp);
if(!flag) flag=1,k=temp;
}
temp=f[temp];
}
if(!flag) k=s;
st.push(s);
while(!st.empty()){
o(st.top());
if(st.size()!=1) p(' ');
else p('\n');
st.pop();
}
o(k);p('\n');
o(d[t+n]);p('\n');
}
}
signed main(){
while(cin>>n>>s>>t){
if(cnt++) p('\n');
in(m);
clear();
For(i,1,m){
in(x);in(y);in(v);
push(x,y,v);
push(y,x,v);
push(x+n,y+n,v);
push(y+n,x+n,v);
}
in(k);
For(i,1,k){
in(x);in(y);in(v);
push(x,y+n,v);
push(y,x+n,v);
}
spfa();
print();
}
return 0;
}
来源:https://www.cnblogs.com/war1111/p/12651476.html