poj 1386 Play on Words(欧拉回路…
来源:互联网 发布:知乎 大误 龙 编辑:程序博客网 时间:2024/06/05 09:01
题意 :有N个盘子,每个盘子上写着一个仅由小写字母组成的英文单词。你需要给这些盘子安排一个合适的顺序,使得相邻两个盘子中,前一个盘子上面单词的末字母等于后一个盘子上面单词的首字母。请你编写一个程序,判断是否能达到这一要求。
思路:这道题,有一个很巧妙的转换,把点变成边。以26个字母作为顶点;对于每一个盘子,如果它的首字母为c1,末字母为c2,那么从c1向c2连一条有向边。如下图。然后判断图连通,再判断它是否为欧拉图PS:因为有重边,用边表建图时(在建图时加判断 用边表也可以),会超时,用邻接矩形比较好 因为只有26个点。
//172K 313MS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define VM 30
int indeg[VM],outdeg[VM],mat[VM][VM],start;
bool vis[VM];
void dfs (int u)
{
for (int i =0; i < 26; i ++)
if (mat[u][i])
{
mat[u][i] = 0;
dfs(i);
}
}
bool cmp()
{
inti,k,sum1,sum2,sum3;
sum1 = sum2= sum3 = 0;
for (i = 0;i < 26; i ++)
{
if (indeg[i] - outdeg[i] == 1)
sum1 ++;
if (outdeg[i] - indeg[i] == 1)
{
sum2 ++;
start = i;
}
if (indeg[i] ==outdeg[i]&&indeg[i]!= 0)
k = i;
if (abs(indeg[i] - outdeg[i]) > 1)
sum3 ++;
}
if (sum1> 1||sum2 > 1||sum3 >0)
return false;
if (sum2 ==0)
start = k;
returntrue;
}
int main ()
{
intT,n;
boolflag;
charstr[1005];
scanf("%d",&T);
while (T--)
{
scanf ("%d",&n);
memset (indeg,0,sizeof(indeg));
memset (outdeg,0,sizeof(outdeg));
memset (mat,0,sizeof(mat));
memset (vis,false,sizeof(vis));
while (n --)
思路:这道题,有一个很巧妙的转换,把点变成边。以26个字母作为顶点;对于每一个盘子,如果它的首字母为c1,末字母为c2,那么从c1向c2连一条有向边。如下图。然后判断图连通,再判断它是否为欧拉图PS:因为有重边,用边表建图时(在建图时加判断 用边表也可以),会超时,用邻接矩形比较好 因为只有26个点。
//172K
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define VM 30
int indeg[VM],outdeg[VM],mat[VM][VM],start;
bool vis[VM];
void dfs (int u)
{
}
bool cmp()
{
}
int main ()
{