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