Codeforces 83C

求字典序最小的最短路
先求最短路,因为边权都为1,所以直接沿着最短路边广搜出一条
字典序最小的就好了

#include
#include
#include
#include
#include
using namespace std;
typedef __int64 LL;
const int N=51;

char tt[10];
char mp[N*N];
char ans[N*N],ans1[N*N];
int c1,c2,c3,c4;
int s,t,clock;
int vis[N][N],dis[N][N],wis[N][N],pre[N][N];
queue<int> qq;
int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
int n,m,k;
char ss[N][N];

////c1 dangqian c2 zong
void fun(){
    //for(int i=0;iprintf("%c ",tt[i]);printf("\n");
    for(int i=0;ifor(int j=0;j<m;j++){
            wis[i][j]=0;
            for(int k1=0;k1if(ss[i][j]==tt[k1])wis[i][j]=1;
            if(ss[i][j]=='S'||ss[i][j]=='T')wis[i][j]=1;
        }
    }

    clock++;
    qq.push(t);dis[t/m][t%m]=0;vis[t/m][t%m]=clock;
    while(!qq.empty()){
        int u=qq.front();qq.pop();
        int x=u/m,y=u%m;
        for(int i=0;i<4;i++){
            int xx=x+dir[i][0],yy=y+dir[i][1];
            if(xx>=0&&xx=0&&yy<m&&wis[xx][yy]){
                if(vis[xx][yy]!=clock){
                    vis[xx][yy]=clock;dis[xx][yy]=dis[x][y]+1;qq.push(xx*m+yy);
                }
            }
        }
    }
    if(vis[s/m][s%m]!=clock||dis[s/m][s%m]-1>c3)return ;
    //printf("%d\n",dis[s/m][s%m]);
    char ch[2]={'S','a'+30};

    int dep=dis[s/m][s%m];
    clock++;
    qq.push(s);vis[s/m][s%m]=clock;pre[s/m][s%m]=-1;
    while(!qq.empty()){
        int u=qq.front();qq.pop();
        int x=u/m,y=u%m;
        if(dis[x][y]x][y],ch[0]=ch[1];ch[1]='a'+30;
        }
        //printf("%d %d %c\n",x,y,ch[0]);
        if(ss[x][y]>ch[0])continue;
        for(int i=0;i<4;i++){
            int xx=x+dir[i][0],yy=y+dir[i][1];
            if(xx>=0&&xx=0&&yy<m&&wis[xx][yy]&&dis[xx][yy]==dep-1){
                if(vis[xx][yy]!=clock){
                    vis[xx][yy]=clock;pre[xx][yy]=u;qq.push(xx*m+yy);
                    ch[1]=min(ch[1],ss[xx][yy]);
                }
            }
        }
    }

    c4=dis[s/m][s%m]-1;
    int u=t;
    for(int i=0;i,y=u%m;
        ans1[c4-i-1]=ss[x][y];
    }
    if(c4==c3){
        for(int i=0;iif(ans[i]>ans1[i])break;
            else if(ans[i]return ;
        }
    }
    for(int i=0;i//for(int i=0;iprintf("%c",ans[i]);printf("\n");
}
int main(){
    #ifdef DouBi
    freopen("in.cpp","r",stdin);
    #endif // DouBi
    while(scanf("%d%d%d",&n,&m,&k)!=EOF){
        c2=0;for(int i=0;i"%s",ss[i]);
            for(int j=0;j<m;j++){
                if(ss[i][j]=='S')s=i*m+j;
                else if(ss[i][j]=='T')t=i*m+j;
                else mp[c2++]=ss[i][j];
            }
        }
        sort(mp,mp+c2);c2=unique(mp,mp+c2)-mp;
        c3=N*N+10;memset(vis,0,sizeof(vis));clock=0;
        fun();
        for(int i=0;i0]=mp[i],c1=1;fun();
            if(c1==k)continue;
            for(int j=i+1;j1]=mp[j],c1=2;fun();
                if(c1==k)continue;
                for(int k1=j+1;k12]=mp[k1],c1=3;fun();
                    if(c1==k)continue;
                    for(int l=k1+1;l3]=mp[l],c1=4;fun();
                    }
                }
            }
        }
        //printf("%d\n",c3);
        if(c3==N*N+10)printf("-1\n");
        else {
            for(int i=0;iprintf("%c",ans[i]);printf("\n");
        }
    }
    return 0;
}

你可能感兴趣的:(图论)