思路:把所有最短路找出来,然后跑一次就好了。
把所有最短路找出来大概就是,把边反向,然后从e跑最短路。
然后正向从s跑最短路。然后从s开始,每次跟着最短路(字典序最小)走。
判断一条边是不是最短路,也就是dis[u]+d[v]+hehe=D
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<map> #include<cmath> #include<queue> #include<cstring> #include<set> #include<stack> #include<string> #include<ctime> #define LL long long #define u64 unsigned long long #define maxn 5010 #define MAX 500010 #define INF 0x3f3f3f3f #define eps 1e-6 using namespace std; struct node { int next,to ; char str[10] ; }edge[MAX]; int head[maxn],dis[maxn],top,d[maxn] ; int mat[30][30] ,pos[maxn] ; bool vi[maxn] ; vector<int>qe[maxn] ; void Unit(int x,int y,char *s) { edge[top].to=y;edge[top].next=head[x] ; strcpy(edge[top].str,s) ;head[x]=top++; } void spfa1(int s,int e,int dis[]) { memset(vi,0,sizeof(vi)) ; vi[s]=true; queue<int>q; q.push(s) ; dis[s]=0; int i,v,u,hehe; while(!q.empty()) { u=q.front();q.pop(); for(i =0 ; i < qe[u].size();i++) { v=qe[u][i]; if(mat[pos[u]][pos[v]])hehe=0; else hehe=1; if(dis[v]>hehe+dis[u]) { dis[v]=hehe+dis[u] ; if(!vi[v]) { vi[v]=true; q.push(v) ; } } } vi[u]=false; } } void spfa(int s,int e,int dis[]) { memset(vi,0,sizeof(vi)) ; vi[s]=true; queue<int>q; q.push(s) ; dis[s]=0; int i,v,u,hehe; while(!q.empty()) { u=q.front();q.pop(); for(i = head[u] ; i != -1;i=edge[i].next) { v=edge[i].to ; if(mat[pos[u]][pos[v]])hehe=0; else hehe=1; if(dis[v]>hehe+dis[u]) { dis[v]=hehe+dis[u] ; if(!vi[v]) { vi[v]=true; q.push(v) ; } } } vi[u]=false; } } void solve(int s,int e,int D) { int i ,id ,hehe ,v ; char str[10] ; bool flag=false; while(s != e) { id=-1; for(i = head[s] ; i != -1 ; i = edge[i].next) { v=edge[i].to; if(mat[pos[s]][pos[v]])hehe=0; else hehe=1; if(hehe+dis[s]+d[v]==D) { if(id==-1) { id=v; strcpy(str,edge[i].str) ; } else if(strcmp(str,edge[i].str) > 1) { id=v; strcpy(str,edge[i].str) ; } } } // cout<<s<<" " << id<<endl; if(id==-1) return ; if(!mat[pos[s]][pos[id]]) { if(flag)printf(" %s",str) ; else printf("%s",str) ; flag=true; } s=id; } puts(""); } void out(int n,int *dis) { for(int i=0;i<n;i++)cout<<dis[i]<<" " ;puts(""); } int main() { int i,n,m,j,len; int T,k,x; char str[32]; cin >> T ; while(T--) { scanf("%d",&n) ; top=0; memset(head,-1,sizeof(head)) ; for(i=0;i<maxn;i++)qe[i].clear(); for( i = 1 ; i <= n ;i++) { scanf("%d%s%d",&k,str,&m) ; pos[k]=str[0]-'A'; while(m--) { scanf("%s%d",str,&j) ; Unit(k,j,str) ; qe[j].push_back(k) ; } } scanf("%d",&m) ; while(m--) { scanf("%d%d%s",&i,&j,str) ; memset(mat,0,sizeof(mat)) ; len=strlen(str) ; for( int i = 0 ; i < len ;i++) for( int j = 0 ; j < len ;j++ ) mat[str[i]-'A'][str[j]-'A']=true; memset(dis,INF,sizeof(dis)) ; memset(d,INF,sizeof(d)) ; spfa1(j,i,d) ; spfa(i,j,dis) ; solve(i,j,dis[j]); } } return 0 ; } /* 2 5 0 A 2 T0 1 T2 2 1 A 1 T1 2 2 A 1 T3 3 3 B 1 T4 4 4 B 1 T5 1 1 0 4 A 6 0 A 2 T0 1 T2 2 1 A 1 T1 2 2 A 2 T3 3 T6 5 3 B 1 T4 4 4 B 1 T5 1 5 A 1 T7 4 2 0 4 A 5 3 A */