Uvalive 6302 Star Travel

思路:把所有最短路找出来,然后跑一次就好了。

把所有最短路找出来大概就是,把边反向,然后从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
*/
View Code

 

你可能感兴趣的:(Uvalive 6302 Star Travel)