説明
ジョンは農家フェンスの多くは、毎年補修する必要があります。彼はフェンスと各修理その壊れた場所を通して馬に乗ります。
ジョンは他の農家と怠惰な人と同じです。彼は乗馬を嫌って、フェンス通じので、二度は決して。あなたはフェンスのネットワークを記述し、フェンスを修復するためにパスを計算読み込むプログラムをコンパイルする必要があり、フェンスそれぞれが一度だけをしてきました。任意の頂点(すなわち2つのフェンスの交点)からのジョンはいずれかの頂点の終わりに、乗馬を開始します。
1-500ラベルを使用して各頂点の2つの頂点に接続されたフェンス(一部は500個の頂点を耕作しなかったが)。頂点は、任意の数(> = 1)フェンスに接続することができます。すべてのフェンスである(つまり、あなたはすべての任意のフェンスフェンスから別のに達することができる)に通信しています。
(ターン数表現を通して道の頂点に)乗ってあなたのプログラムを出力しなければならないパス。我々はパスを入れた場合500は、それがある場合に、複数の溶液、表記500を出力する最小のもの(すなわちA第小さい出力番号が存在する場合には、その後、進数として出力されます。複数の溶液、第二のより小さい出力数、等)。
少なくともデータ入力ソリューションいることを確認してください。
入力
整数F(1 <= F <= 1024)、 フェンスを示す:1行
F + 1行に2:各行二つの整数I、J(1 <= I 、J <= 500) を示していますj番目の頂点Iに接続されている記事のフェンス。
出力
F + 1は、それぞれ線順次頂点パスパスの整数、出力線べきです。データは、しかし被験者の要件上記溶液が正しいと見なされるだけで、複数のソリューションを有することができることに留意されたいです。
サンプル入力
9
1 2
2 3
3 4
4 2
4 5
2 5
5 6
5 7
4 6
サンプル出力
1
2
3
4
2
5
4
6
5
7
問題解決のためのアイデア
(ナンセンス):ビットを見つけるためにインターネットへの無知に見えることを余儀なくオイラーを、オイラーはかろうじて再生する方法を理解し、オイラーロードした後、Aのタイトルを置きます。。。:)
オイラーサイクルは、回路のエッジの存在の表示を与えることであり、各エッジを介して一度だけ通過します。(プレゼンテーションにコピーします)
フレームのため。DFSはそれを使用することですが、バックしながら、現在の道路上のマークを解除した後、最終的に戻ってポイントに、オーダーのポイントだけで罰金を記録していないときのように:(仕方なく要約)
無向グラフの場合:(連続レプリケーション)
- オイラーの存在:各点の偶数です。
- プレゼンスオイラー経路:のみ2点のはそれぞれ1と、2つの開始点と終了点、です。
出発点のために:次数が奇数である場合は、最初に存在しないオイラー経路の存在を決定し、各点の記録は、次いで、出発点としてのTaを入れ、この無向グラフを(見つけるために小から大まで覚えている)の奇数のない点がない場合(辞書最小に起因する)開始から、最初の点(SO等)
私は今、良いと無知Bああを感じます
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=500;
int a[maxn*4],n,maxx,b[maxn*2][maxn*2],s[maxn*2],num,minn=maxn*4;
void DFS(int x){
for(int i=1;i<=maxx;i++){
if(b[x][i]>0){
b[x][i]--;b[i][x]--;//忘了两条边都要标记,Debug了好久
DFS(i);
//不需要回溯删除对边的标记
}
}
a[++num]=x;//回溯回来,把点记录下来
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
int x,y;
scanf("%d%d",&x,&y);
b[x][y]++;b[y][x]++;//一开始没看到有多条边(机房惨案)
minn=min(minn,min(x,y));
maxx=max(maxx,max(x,y));
s[x]++,s[y]++;//记录度
}
int start=minn;//起点初值第一个点
for(int i=minn;i<=maxx;i++){
if(s[i]%2==1){//度为奇数
start=i;//设为起点
break;
}
}
DFS(start);
for(int i=num;i>0;i--)
printf("%d\n",a[i]);//因为回溯才存,所以顺序是倒的
}