タイトル説明
牛は侵略されています!その共和国は、N(1 <= N <= 50,000)は、2つの町a_iをとB_i(1 <= a_iを<= Nの間にM(1 <= M <=10万)無向経路で接続されている町と、1 <= B_iを< = N;!a_iを= B_i;重複パスは発生しません)。しかし共和国は必ずしも接続されていない - 経路を介して相互に到達することができない町のペアが存在してもよいです。
牛は彼らの侵略者が自分の共和国内のすべてのパスのインベントリを実施する予定知っているので、彼らは彼らの侵略者がそうするために可能な限り困難としてそれを作るために、様々なパスをシャットダウンして喜んでいます。
牛が各町がそれに接続された残りのパスの奇数を有する、またはそのようなサブセットが存在しないかどうかを決定するようにパスのサブセットをシャットダウンする方法を見つける助けてください。
たとえば、以下の牛の共和国を考えてみます。
1 --- 2 \ / 3 --- 4我々は1-3、2-3、3-4パスを維持し、パス1-2を削除する場合、町1、2、および4は、エンドポイントであろう正確に一つのパスでは、町のに対し、3は3つの経路の終点になります。
1 2 \ / 3 --- 4
入力形式
* 1行目:二スペースで区切られた整数:NとM
*行2..M + 1:a_iをとB_i:行I + 1は2スペースで区切られた整数を含みます
出力フォーマット
* 1行目:維持するパスの数である単一の整数。いかなるサブセットは整数で出力単一ラインを存在しない場合は-1。
*ライン2..K + 1:各行は、範囲1..Mに、保持するパスのインデックスを含みます。これらのインデックスは、ペアごとに異なるでなければなりません。
問題の意味の翻訳
問題の意味
牛は侵略されました。そこN によるNポイント、M M側への無料接続。無向エッジa_iをA I とB_i B I 。側というデータを確実にないように重量が、(すなわち、ある地点から別の地点に到達することができない)通信を保証するものではありません。
牛は、彼らが可能な困難な限り侵入者の計画のエッジの一部をカットしたいので、すべてのエッジの彼らの在庫を侵略することを計画しているかを知ります
各点のみ奇数エッジがそれに接続されたように、いくつかのエッジを残すための方法を見つけるしてください。そして、プログラムの出力側は取り残さ。
ここではサンプルです
1---2
\ /
3---4
我们把1——2那条边拆掉, 就会变成下图
1 2
\ /
3---4
对于每个点都只有奇数条边连接,符合题意
出力形式を読み込み
読む・フォーマット
- 二つの整数の最初のライン N Nおよび M M
- 第2 M + 1 、M + 1行、各側は、二つの整数説明したa_iをA I とB_i B Iを
出力フォーマット
- 残りのエッジの整数、-1の出力の最初の行はください不可能な場合
- 各ラインの番号の後に、辺の数(入力の順序によって)。
@ToBiChi翻訳をありがとう
サンプル入力と出力
説明/ヒント
@cnありがとう:特別審査員ス・クインディアンを提供しました
思考
図は、リーフ縁部によって検索処理で更新を開始し、現在の選択の上縁の葉の奇数葉を添加実証する必要がない場合でも、DFSに対するシーケンスを更新することができます
コード
#include
<
ビット/ STDC ++。H
>
#define
DBG(
X
)
COUT
<<
#X
<<
"
=
"
<<
X
<<
ENDL
#defineは
epsは
1個の
電子を
-
8
#define
パイ
ACOS(
-
1.0
)
使用して
名前空間
はstdを
、
typedefの
長い
長い
LL
。
const
int型
INF
=
0xの
3f3f3f3f
。
template
<
class T
>
inline
void
read(T
&
res
)
{
char c
;T flag
=
1
;
while((c
=
getchar())
<
'
0
'
||c
>
'
9
'
)if(c
==
'
-
'
)flag
=-
1
;res
=c
-
'
0
'
;
while((c
=
getchar())
>=
'
0
'
&&c
<=
'
9
'
)res
=res
*
10
+c
-
'
0
'
;res
*=flag
;
}
namespace _buff
{
const
size_t BUFF
=
1
<<
19
;
char
ibuf
[BUFF
],
*ib
= ibuf
,
*ie
= ibuf
;
char
getc()
{
if
(ib
== ie
)
{
ib
= ibuf
;
ie
= ibuf
+
fread(ibuf
,
1
, BUFF
, stdin
);
}
return ib
== ie
?
-
1
:
*ib
++
;
}
}
int
qread()
{
using
namespace _buff
;
int ret
=
0
;
bool pos
=
true
;
char c
=
getc();
for
(;
(c
<
'
0
'
|| c
>
'
9
'
)
&& c
!=
'
-
'
; c
=
getc())
{
assert(
~c
);
}
if
(c
==
'
-
'
)
{
pos
=
false
;
c
=
getc();
}
for
(; c
>=
'
0
'
&& c
<=
'
9
'
; c
=
getc())
{
ret
=
(ret
<<
3
)
+
(ret
<<
1
)
+
(c
^
48
);
}
return pos
? ret
:
-ret
;
}
const
int maxn
=
1
e
5
+
7
;
int n
, m
, cnt
;
int
edge
[maxn
<<
1
],
head
[maxn
<<
1
],
nxt
[maxn
<<
1
];
int
id
[maxn
<<
1
];
void
BuildGraph(
int
u
,
int
v
,
int
idx
)
{
++cnt
;
edge
[cnt
]
= v
;
nxt
[cnt
]
=
head
[u
];
head
[u
]
= cnt
;
id
[cnt
]
= idx
;
}
vector
<int> ans
;
bool
vis
[maxn
];
bool
dfs(
int
u
,
int
fa
,
int
idx
)
{
int du
=
0
;
vis
[u
]
=
1
;
for
(
int i
=
head
[u
]; i
; i
=
nxt
[i
]
)
{
int v
=
edge
[i
];
if(
vis
[v
]
|| v
== fa
)
continue;
if(dfs(v
, u
,
id
[i
]))
++du
;
}
if(du
&
1
)
{
return
false
;
}
ans
.push_back(idx
);
return
true
;
}
int
main()
{
read(n
);read(m
);
for
(
int i
=
1
; i
<= m
;
++i
)
{
int u
, v
;
read(u
);read(v
);
BuildGraph(u
, v
, i
);
BuildGraph(v
, u
, i
);
}
for
(
int i
=
1
; i
<= n
;
++i
)
{
if(
vis
[i
])
continue;
if(dfs(i
,
0
,
0
))
{
puts(
"
-1
"
);
return
0
;
}
}
int d
=
ans
.size();
cout
<< d
<< endl
;
for
(
int i
=
0
; i
< d
;
++i
)
{
cout
<<
ans
[i
]
<< endl
;
}
return
0
;
}