poj 1386
来源:互联网 发布:诲女知之乎悔 编辑:程序博客网 时间:2024/06/05 04:29
图论的题目,用并查集判断连通,然后判断欧拉路径存在。
题目中给你n个字符串,问你能不能找到一种排列方案,使前一个单词的尾部字符是下一个单词的首部字母。
这里我们要将问题转化,将一个单词看成一条边。将首尾两个字符分别看做两个节点,中间字母全部忽略
比如数据1:
acmibm
acm 是一条 a->m的边
ibm 是一条 i->m的边
判断存不存一条欧拉通路能够遍历每一条边,注上述问题的单词已经被我转化为一条有向边,然后前一个单词的尾部字符是下一个单词的首部字母这一条件就是两个单词的共同节点。判断有向图欧拉回路直接统计每一个节点的出入度即可。
注意点:
图可能不连通,要用并查集判断,判断方法就是将一条边上的两个点连接,最后判断所有点是不是一个集合内即可。
代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int F[30];
int find(int x)
{
if(F[x] == -1)return x;
else return F[x] = find(F[x]);
}
void bing(int u,int v)
{
int t1 = find(u);
int t2 = find(v);
if(t1 != t2)F[t1] = t2;
}
char str[1010];
int in[30],out[30];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
int n;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
memset(F,-1,sizeof(F));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
int s = -1;
while(n--)
{
scanf("%s",str);
int len = strlen(str);
int u = str[0] - 'a';
int v = str[len-1] - 'a';
bing(u,v);
out[u]++;in[v]++;
if(s == -1)s = u;
}
bool flag = true;
int cc1 = 0,cc2 = 0;
for(int i = 0;i < 26;i++)
{
if(out[i] - in[i] == 1)cc1++;
else if(out[i] - in[i] == -1) cc2++;
else if(out[i] != in[i])
flag = false;
if(out[i] || in[i])
if(find(i) != find(s))
flag = false;
}
if( !( (cc1 == 0 && cc2 == 0) || (cc1 == 1 && cc2 == 1) ) )
flag = false;
if(flag)
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
}
return 0;
}
- poj 1386
- poj-1386
- poj 1386
- poj--1386
- POJ 1386(欧拉路)
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- UDP:用户数据报
- Toplogical Sort 拓扑排序
- NVMain运行机制深入了解之二
- HTML5练习(1)制作满天星
- 理解Spark的RDD
- poj 1386
- 另一个思路注入的实现
- POJ 3368 经典RMQ
- Matlab 小波变换dwt和wavedec
- flex分页2 新新的,一页多次调用互相不冲突
- Java编程思想-注解生成外部例子代码
- 第13周项目5 -字符串操作(2.4)
- iOS8中,程序接收不到应用调用系统服务提示的解决方案
- 用servlet写的一个简单的下载文件功能