122. The book

time limit per test: 0.25 sec. 
memory limit per test: 4096 KB

There is a group of N (2<=N<=1000) people which are numbered 1 through N, and everyone of them has not less than [ (N+1) / 2 ] friends. A man with number 1 has the book, which others want to read. Write the program which finds a way of transferring the book so that it will visit every man only once, passing from the friend to the friend, and, at last, has come back to the owner. Note: if A is a friend of B then B is a friend of A.

Input

First line of input contains number N. Next N lines contain information about friendships. (i+1)-th line of input contains a list of friends of i-th man.

Output

If there is no solution then your program must output 'No solution'.   Else your program must output exactly N+1 number: this sequence should begin and should come to end by number 1, any two neighbours in it should be friends, and any two elements in it, except for the first and last, should not repeat.

Sample Input

4
2 3
1 4
1 4
2 3

Sample Output

1 3 4 2 1

1.找到一条不能延伸的路径,此时设左边为st,右边为ed,那么一定满足的性质是,st和ed所能到达的所有点都在这条路上,又由于这个图的性质,两点度数加和一定大于n+1,
根据鸽巢原理,总能找到一个点j,使得j连接ed,nxt[j]连接st,这时候删除j->nxt[j],得到一个环
2.找到一个在环外的点,拆环并且延伸路径
重复这两步直到形成长度为n的环
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1001;
int n;
bool vis[maxn],use[maxn];
int G[maxn][maxn],len[maxn],pre[maxn],nxt[maxn],st,ed;
int predfs(int cnt){
vis[st]=true;
for(int i=0;i<len[st];i++){
int to=G[st][i];
if(!vis[to]){pre[st]=to;nxt[to]=st;st=to;return predfs(cnt+1);}
}
return cnt;
}
int nxtdfs(int cnt){
vis[ed]=true;
for(int i=0;i<len[ed];i++){
int to=G[ed][i];
if(!vis[to]){nxt[ed]=to;pre[to]=ed;ed=to;return nxtdfs(cnt+1);}
}
return cnt;
}
bool getloop(){
if(st==ed)return true;
for(int i=0;i<len[ed];i++){
int to=G[ed][i];
if(to==st){pre[st]=ed;nxt[ed]=st;return true;}
for(int j=0;j<len[nxt[to]];j++){
int jto=G[nxt[to]][j];
int tt=nxt[to];
if(jto==st){
int tmp;
while(st!=ed){
nxt[ed]=to;
tmp=pre[to];
pre[to]=ed;
ed=to;
to=tmp;
}
nxt[st]=tt;
pre[tt]=st;
return true;
}
}
}
return false;
}
bool breakloop(){
for(int i=1;i<=n;i++){
if(!vis[i]){
for(int j=0;j<len[i];j++){
if(vis[G[i][j]]){
st=i;
ed=pre[G[i][j]];
nxt[i]=G[i][j];
pre[G[i][j]]=st;
return true;
}
}
}
}
return false;
}
void printloop(){
int sst=1,tmp=1;
bool fl=false;
while(sst!=tmp||!fl){
printf("%d ",tmp);
if(nxt[tmp]==tmp)break;
tmp=nxt[tmp];
fl=true;
}
puts("1");
}
void addedge(int f,int t){
G[f][len[f]++]=t;
}
int main(){
scanf("%d",&n);
getchar();
for(int i=1;i<=n;i++){
int tmpt;
while(scanf("%d",&tmpt)==1){
if(tmpt!=i)addedge(i,tmpt);
if(i==1)use[tmpt]=true;
char ch=getchar();
if(ch=='\n')break;
}
}
int len=1;
st=ed=1;
while(len<n){
len+=predfs(0);
len+=nxtdfs(0);
if(len==n)break;
if(!getloop())break;
if(!breakloop())break;
len++;
}
getloop();
if(len<n)puts("No solution");
printloop();
return 0;
}

  

sgu 122. The book 满足ore性质的汉密尔顿回路 难度:2的更多相关文章

  1. SGU 156 Strange Graph 欧拉回路,思路,汉密尔顿回路 难度:3

    http://acm.sgu.ru/problem.php?contest=0&problem=156 这道题有两种点 1. 度数>2 在团中的点,一定连接一个度数为2的点 2. 度数等 ...

  2. The sum - SGU 122(斐波那契前N项和)

    直接上代码....... ======================================================================================= ...

  3. SGU 122.The book (哈密顿回路)

    题目描述 有一群人从1到N标号,而且这群人中每个人的朋友个数不少于 (N+1)/2 个. 编号为1的人有一本其他人都想阅读的书. 写一个程序,找到一种传阅顺序使得书本只经过每个人手中一次,并且一个人只 ...

  4. 今日SGU 5.27

    SGU 122 题意:给你n个人,每个人有大于 N / 2(向上取整)的朋友,问你1这个人有一个书,每个人都想看,只能从朋友之间传递,然后最后回到了1这个人,问你 是否有解,然后有解输出路径 收获:哈 ...

  5. javascript输出图的简单路径

    <script> //图的构建 function vnode() { this.visited=0; this.vertex=0; this.arcs=new Array(); } fun ...

  6. P、NP、NPC、NPH问题的区别和联系

    时间复杂度 时间复杂度描述了当输入规模变大时,程序运行时间的变化程度,通常使用\(O\)来表示.比如单层循环的时间复杂度为\(O(n)\),也就是说程序运行的时间随着输入规模的增大线性增长,两层循环的 ...

  7. Pow共识算法

    谈到哈希算法,每个程序员都不陌生,但是谈到比特币共识算法PoW,如果没有接触过的技术人员可能觉得应该会很复杂,毕竟全球的比特币节点数量如此庞大,达成共识的算法应该不会很简单.但其实如果你已掌握哈希算法 ...

  8. 初赛Part2

    初赛 时间复杂度 主定理(必考) \[ T(n) = aT(\frac{n}{b})+f(n) \] 其中,\(n\)为问题的规模,\(a\)为递推下子问题的数量,\(\frac{n}{b}\)为每个 ...

  9. SGU 101.Domino (欧拉路)

    时间限制: 0.5 sec 空间限制: 4096 KB 描述 多米诺骨牌,一种用小的方的木块或其他材料,每个都被一些点在面上标记,这些木块通常被称为骨牌.每个骨牌的面都被一条线分成两个   方形,两边 ...

随机推荐

  1. vijos 1360 八数码问题 - 启发式搜索

    背景 Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们. 描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0 ...

  2. Timer,TimerTask,Handler

    新建一个定时器线程,通过此线程每一秒发送数据到Handler,然后通过Handler来修改UI. 1.获得Handler,Timer,TimerTask对象. Handler handler=new ...

  3. python函数作用域LEGB

    我们的在学习Python函数的时候,经常会遇到很多定义域的问题,全部变量,内部变量,内部嵌入的函数,等等,Python是如何查找的呢?以及Python又是按照什么顺序来查找的呢?这里做一个顺序的说明 ...

  4. POJ 1260 Pearls (斜率DP)题解

    思路: 直接DP也能做,这里用斜率DP. dp[i] = min{ dp[j] + ( sum[i] - sum[j] + 10 )*pr[i]} ; k<j<i  =>  dp[j ...

  5. C#中的编译开关

    c#不支持宏定义,只支持编译开关. ======================================我想加上#define xxx就编译a代码,否则编译b代码,像这样的:#if xxxa ...

  6. 如何加速tomcat启动速度

    在tomcat启动的时候,我们可以做一些优化设置来使得tomcat的启动更快速,下面是一些常见的优化加速启动的方法建议(以tomcat-7.+为例说明). 1.  Jars包 1.1.将一些不必要的j ...

  7. perl usage()和getopt

    #!/usr/bin/perl#perl search.pl --infile Targets.Lung.Carcinoma.genelist.txt --homogene Homo_sapiens. ...

  8. 关于react native的快捷键和常用规范

    一:快捷键 1.让其自更新----shift+cmd+z 选择热更新 2.cmd+r ---重新刷新 3 二:常用规范: 1.文件也是一种组件 所以应该命名规则和组件名的命名规则相同  -----使用 ...

  9. vue-echarts的使用及编译报错解决方法

    一. 使用 vue-cli 快速构建vue项目, 引入vue-echarts组件 安装:  > npm i vue-echarts --save 修改 webpack.config.js 配置: ...

  10. shell 布尔运算符

    布尔运算符 下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20: 运算符 说明 举例 ! 非运算,表达式为 true 则返回 false,否则返回 true. [ ! false ...