標籤:
思路:把所有最短路找出來,然後跑一次就好了。
把所有最短路找出來大概就是,把邊反向,然後從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-6using 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 ;}/*250 A 2 T0 1 T2 21 A 1 T1 22 A 1 T3 33 B 1 T4 44 B 1 T5 110 4 A60 A 2 T0 1 T2 21 A 1 T1 22 A 2 T3 3 T6 53 B 1 T4 44 B 1 T5 15 A 1 T7 420 4 A5 3 A*/View Code
Uvalive 6302 Star Travel