Codeforces 83C

来源:互联网 发布:天龙八部源码 编辑:程序博客网 时间:2024/05/11 17:26

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

#include<cstdio>#include<iostream>#include<cstring>#include<queue>#include<algorithm>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 zongvoid fun(){    //for(int i=0;i<c1;i++)printf("%c ",tt[i]);printf("\n");    for(int i=0;i<n;i++){        for(int j=0;j<m;j++){            wis[i][j]=0;            for(int k1=0;k1<c1;k1++)if(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<n&&yy>=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]<dep){            dep=dis[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<n&&yy>=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<c4;i++){        u=pre[u/m][u%m];        int x=u/m,y=u%m;        ans1[c4-i-1]=ss[x][y];    }    if(c4==c3){        for(int i=0;i<c3;i++){            if(ans[i]>ans1[i])break;            else if(ans[i]<ans1[i])return ;        }    }    for(int i=0;i<c4;i++)ans[i]=ans1[i];c3=c4;    //for(int i=0;i<c3;i++)printf("%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<n;i++){            scanf("%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;i<c2;i++){            tt[0]=mp[i],c1=1;fun();            if(c1==k)continue;            for(int j=i+1;j<c2;j++){                tt[1]=mp[j],c1=2;fun();                if(c1==k)continue;                for(int k1=j+1;k1<c2;k1++){                    tt[2]=mp[k1],c1=3;fun();                    if(c1==k)continue;                    for(int l=k1+1;l<c2;l++){                        tt[3]=mp[l],c1=4;fun();                    }                }            }        }        //printf("%d\n",c3);        if(c3==N*N+10)printf("-1\n");        else {            for(int i=0;i<c3;i++)printf("%c",ans[i]);printf("\n");        }    }    return 0;}
0 0
原创粉丝点击