欧拉回路

【题目描述】:
有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。
一共两个子任务:
这张图是无向图。( 50分)
这张图是有向图。( 50分)
【输入描述】:
第一行一个整数 t,表示子任务编号。t∈{1,2},如果 t=1则表示处理无向图的情况,如果 t=2则表示处理有向图的情况。
第二行两个整数 n,m,表示图的结点数和边数。
接下来 m 行中,第 i 行两个整数 vi,ui,表示第 i 条边(从 1 开始编号)。保证 1≤vi,ui≤n。
如果 t=1 则表示 vi 到 ui 有一条无向边。
如果 t=2 则表示 vi 到 ui 有一条有向边。
图中可能有重边也可能有自环。
【输出描述】:

如果不可以一笔画,输出一行 “NO”。

否则,输出一行 “YES”,接下来一行输出一组方案。

如果 t=1,输出 mm 个整数 p1,p2,…,pm。令 e=|pi|,那么 e 表示经过的第 i 条边的编号。如果 pi 为正数表示从 ve 走到 ue,否则表示从 ue 走到 ve。

如果 t=2,输出 m 个整数 p1,p2,…,pm。其中 pi 表示经过的第 i 条边的编号。
【样例输入1】:

1
3 3
1 2
2 3
1 3

【样例输出1】:

YES
1 2 -3

【样例输入2】:

2
5 6
2 3
2 5
3 4
1 2
4 2
5 1

【样例输出2】:

YES
4 1 3 5 2 6

【时间限制、数据范围及描述】:

时间:1s 空间:256M

1<=n<=105;0<=m<=2×10^5
思路:
欧拉回路的模板,注意ans要倒着输出
【code】

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cmath>
 4 #include <vector>
 5 using namespace std;
 6 int head[500006];
 7 bool vis[500005];
 8 struct node {
 9     int to,nxt,from,u;
10 } e[500005];
11 vector<int> ans;
12 int cnt;
13 int in[500005],out[500005];
14 void add(int u,int v) {
15 
16     e[++cnt].to=v;
17     e[cnt].nxt=head[u];
18     head[u]=cnt;
19 }
20 int type,n,m;
21 struct fxysb {
22     int in,out;
23 } sum[500005];
24 int tot,top;
25 void dfs(int x) {
26     for (int &j = head[x]; j; j = e[j].nxt) {
27         int z = j;
28         if (type == 1) {
29             int k = (j + 1) >> 1;
30             if (!vis[k]) {
31                 vis[k] = 1;
32                 dfs(e[j].to);
33                 if ((z & 1) == 0)
34                     ans.push_back(k);
35                 else
36                     ans.push_back(-k);
37             }
38         } else if (!vis[j]) {
39             vis[j] = 1;
40             dfs(e[j].to);
41             ans.push_back(z);
42         }
43     }
44 }
45 int main() {
46     cin>>type>>n>>m;
47     for(int i=1; i<=m; i++) {
48         int x,y;
49         scanf("%d%d",&x,&y);
50             out[x]++;    in[y]++;
51         add(x,y);
52         if(type==1)add(y,x);
53     }
54     if(type==1) {
55         for(int i=1; i<=n; i++) {
56             if((in[i]+out[i])%2) {
57                 cout<<"NO"<<endl;
58                 return 0;
59             }
60         }
61     } else {
62         for(int i=1; i<=n; i++) {
63             if(in[i]!=out[i]) {
64                 cout<<"NO"<<endl;
65                 return 0;
66             }
67         }
68     }
69     for(int i=1; i<=n; i++) {
70         if(head[i]) {
71             dfs(i);
72             break;
73         }
74     }
75     if(ans.size()!=m) {
76         cout<<"NO"<<endl;
77         return 0;
78     }
79     cout<<"YES"<<endl;
80     if(type==1) {
81         for(int i=0; i<=m-1; i++)
82             printf("%d ",ans[i]);
83         return 0;
84     }
85     for(int i=m-1; i>=0; i--)
86         printf("%d ",ans[i]);
87     cout<<endl;
88     return 0;
89 }

 



posted @ 2019-07-15 12:10  GTR_PaulFrank  阅读(136)  评论(0编辑  收藏  举报