刷题记录-luoguP1341 无序字母对

xiaoxiao2021-02-27  293

这是一道欧拉路径的问题

欧拉路径:对于无向图,当且仅当奇数度为0或2时,存在欧拉路径,即可以不重复的经过每一条边。

(1)当奇数度为0时,即所有节点的边数都是偶数时,肯定能回来(n条边,n/2条出来,n/2条回来),故叫做欧拉回路

(2)当奇数度为2时,这两个相应的奇数度节点一定一个是起点,一个是终点,否则做不到不重复的经过每一条边。

*************************************

对于这题,可以把字母对拆开,

对于样例:

4 aZ tZ Xt aX 可拆成:a Z t X

然后连无向边,比如aZ就把a和Z连起来

计算节点的度数,相应的按照欧拉路径来处理,

对于(1),可按照优先级搜索,保存边的vector可以排序,很方便

对于(2),设两点为v u,如果v<u直接以v为起点搜下,否则以u为起点搜下

注意:记录使用的b数组(或者说“used”数组),是记录边的使用,不是节点的使用情况

如果记录节点,那么可能是aZ Zt ta,这样会炸的。

***************************************

#include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #define MAXN 3005 #define MAXM 65 using namespace std; int n; vector<int> G[MAXM]; int b[MAXM][MAXM]; int ans[MAXN]; int temp[MAXM]; int cnt; int dfs(int x,int k){     if(k>n-cnt){         return 1;     }     for(int i=0;i<G[x].size();i++){         int y=G[x][i];         if(!b[x][y]){             b[x][y]=b[y][x]=1;             if(dfs(y,k+1)){                 ans[k]=y;                 return 1;             }             b[x][y]=b[y][x]=0;         }     } } int read(){     scanf("%d",&n);     for(int i=1;i<=n;i++){         char x,y;         cin>>x>>y;         x-='A'; y-='A';         if(x==y){             G[x].push_back(y);         }         else{             G[x].push_back(y);             G[y].push_back(x);             temp[x]++;             temp[y]++;         }     }         for(int i=0;i<MAXM;i++){         sort(G[i].begin(),G[i].end());     }     int cnt=0;     for(int i=0;i<MAXM;i++){         if((temp[i]&1)){             cnt++;         }     } //    for(int i=0;i<MAXM;i++){ //        if(G[i].size()){ //            for(int j=0;j<G[i].size();j++) //                printf("(%c,%c)\n",i+'A',G[i][j]+'A'); //        } //    }     if(cnt&&cnt!=2){         printf("No Solution\n");         return 1;     }     if(cnt){         int u=0,v=0;         for(int i=0;i<MAXM;i++){             if((temp[i]&1)){                 if(u){                     v=i;                     break;                 }                 else{                     u=i;                 }             }         }         if(u<v){             ans[0]=u;             dfs(u,1);         }             else{             ans[0]=v;             dfs(v,1);         }             for(int i=0;i<=n;i++){             printf("%c",ans[i]+'A');         }         return 1;     }     return 0; } int main() { //    freopen("data.in","r",stdin); //    freopen("my.out","w",stdout);     if(read())         return 0;     cnt=1;     for(int i=0;i<MAXM;i++){         if(temp[i]){             ans[0]=i;             ans[n]=i;             if(dfs(i,1)){                 for(int i=0;i<=n;i++){                     printf("%c",ans[i]+'A');                 }                 return 0;             }         }     }     return 0; }

转载请注明原文地址: https://www.6miu.com/read-7174.html

最新回复(0)