一本通1527欧拉回路

1527:【例 1】欧拉回路

时间限制: 1000 ms         内存限制: 262144 KB

【题目描述】

原题来自:UOJ #117

有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。

一共两个子任务:

这张图是无向图。(50 分)

这张图是有向图。(50 分)

【输入】

第一行一个整数 t,表示子任务编号。t{1,2},如果 t=1 则表示处理无向图的情况,如果 t=2 则表示处理有向图的情况。

第二行两个整数 n,m,表示图的结点数和边数。

接下来 m 行中,第 i 行两个整数 vi,ui ,表示第 i 条边(从 1 开始编号)。保证 1vi,uin

如果 t=1 则表示 vi 到 ui 有一条无向边。

如果 t=2 则表示 vi 到 ui 有一条有向边。

图中可能有重边也可能有自环。

【输出】

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

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

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

如果 t=2,输出 m 个整数 p1,p2,,pm 。其中 pi 表示经过的第 条边的编号。

【输入样例】

1
3 3
1 2
2 3
1 3

【输出样例】

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

数据范围与提示:

1n10^5,0m2×10^5

--------------------------放了一大坨概念在下面--------------------------

欧拉回路和欧拉路径的几个概念:

欧拉环:图中经过每条边一次且仅一次的环;

欧拉路径:图中经过每条边一次且仅一次的路径;
欧拉图:有至少一个欧拉环的图;
半欧拉图:没有欧拉环,但有至少一条欧拉路径的图。

【无向图】
一个无向图是欧拉图当且仅当该图是连通的(注意,不考虑图中度为0的点,因为它们的存在对于图中是否存在欧拉环、欧拉路径没有影响)且所有点的度数都是偶数;一个无向图是半欧拉图当且仅当该图是连通的且有且只有2个点的度数是奇数(此时这两个点只能作为欧拉路径的起点和终点);

证明:因为任意一个点,欧拉环(或欧拉路径)从它这里进去多少次就要出来多少次,故(进去的次数+出来的次数)为偶数,又因为(进去的次数+出来的次数)=该点的度数(根据定义),所以该点的度数为偶数。

【有向图】
一个有向图是欧拉图当且仅当该图的基图(将所有有向边变为无向边后形成的无向图,这里同样不考虑度数为0的点)是连通的且所有点的入度等于出度;一个有向图是半欧拉图当且仅当该图的基图是连通的且有且只有一个点的入度比出度少1(作为欧拉路径的起点),有且只有一个点的入度比出度多1(作为终点),其余点的入度等于出度。

证明:与无向图证明类似,一个点进去多少次就要出来多少次。

模板嘛。。。

  1 /*
  2     不懂为什么dfs里的i加个&可以快这么多 
  3 */
  4 #pragma comment(linker, "/STACK:102400000,102400000")
  5 #include <bits/stdc++.h>
  6 using namespace std;
  7 const int N=100005,M=500005;
  8 inline int read()
  9 {
 10     int s=0,f=0;
 11     char ch=' ';
 12     while(!isdigit(ch))
 13     {
 14         f|=(ch=='-');
 15         ch=getchar();
 16     }
 17     while(isdigit(ch))
 18     {
 19         s=(s<<3)+(s<<1)+(ch^48);
 20         ch=getchar();
 21     }
 22     return (f)?(-s):(s);
 23 }
 24 #define R(x) x=read()
 25 inline void write(int x)
 26 {
 27     if(x<0)
 28     {
 29         putchar('-');
 30         x=-x;
 31     }
 32     if(x<10)
 33     {
 34         putchar(x+'0');
 35         return;
 36     }
 37     write(x/10);
 38     putchar((x%10)+'0');
 39     return;
 40 }
 41 inline void writeln(int x)
 42 {
 43     write(x);
 44     putchar('\n');
 45     return;
 46 }
 47 #define W(x) write(x),putchar(' ')
 48 #define Wl(x) writeln(x)
 49 int n,m,T;
 50 int Indeg[N],Outdeg[N],Deg[N];
 51 namespace Oulahuilu
 52 {
 53     int tot=0,Next[M],to[M],head[N];
 54     bool Arr[M];
 55     inline void add(int x,int y)
 56     {
 57         Next[++tot]=head[x];
 58         to[tot]=y;
 59         head[x]=tot;
 60         return;
 61     }
 62     int Huilu[M],Huilu_cnt=0;
 63     inline void Run(int x)
 64     {
 65         for(int &i=head[x];i;i=Next[i]) if(!Arr[i])
 66         {
 67             int oo=i;
 68             Arr[i]=1;
 69             if(T==1)
 70             {
 71                 (i&1)?(Arr[i+1]=1):(Arr[i-1]=1);
 72             }
 73             Run(to[i]);
 74             Huilu[++Huilu_cnt]=oo;
 75         }
 76         return;
 77     }
 78     inline void Output() 
 79     {
 80         int i;
 81         for(i=Huilu_cnt;i>=1;i--)
 82         {
 83             if(T==1)
 84             {
 85                 W(((Huilu[i]&1)?1:-1)*((Huilu[i]+1)/2));
 86             }
 87             else
 88             {
 89                 W(Huilu[i]);
 90             }
 91         }
 92         return;
 93     }
 94 }
 95 int main()
 96 {
 97 //    freopen("tour14.in","r",stdin);
 98 //    freopen("my.out","w",stdout);
 99     int i;
100     R(T);
101     R(n);
102     R(m);
103     if(T==1)
104     {
105         
106         for(i=1;i<=m;i++)
107         {
108             int x,y;
109             R(x);
110             R(y);
111             Deg[x]++;
112             Deg[y]++;
113             Oulahuilu::add(x,y);
114             Oulahuilu::add(y,x);
115         }
116         for(i=1;i<=n;i++) if(Deg[i]&1)
117         {
118             return 0*puts("NO");
119         }
120         for(i=1;i<=n;i++) if(Oulahuilu::head[i])
121         {
122             Oulahuilu::Run(i);
123             break;
124         }
125         if(Oulahuilu::Huilu_cnt!=m)
126         {
127             puts("NO");
128         }
129         else
130         {
131             puts("YES");
132             Oulahuilu::Output();
133         }
134     }
135     else
136     {
137         for(i=1;i<=m;i++)
138         {
139             int x,y;
140             R(x);
141             R(y);
142             Outdeg[x]++;
143             Indeg[y]++;
144             Oulahuilu::add(x,y);
145         }
146         for(i=1;i<=n;i++) if(Indeg[i]!=Outdeg[i])
147         {
148             return 0*puts("NO");
149         }
150         for(i=1;i<=n;i++) if(Oulahuilu::head[i])
151         {
152             Oulahuilu::Run(i);
153             break;
154         }
155         if(Oulahuilu::Huilu_cnt!=m)
156         {
157             puts("NO");
158         }
159         else
160         {
161             puts("YES");
162             Oulahuilu::Output();
163         }
164     }
165     return 0;
166 }
167 /*
168 input
169 1
170 3 3
171 1 2
172 2 3
173 1 3
174 output
175 YES
176 1 2 -3
177 
178 input
179 2
180 5 6
181 2 3
182 2 5
183 3 4
184 1 2
185 4 2
186 5 1
187 output
188 YES
189 4 1 3 5 2 6
190 
191 input
192 2
193 100000 3
194 41700 41700
195 15415 31090
196 31090 15415
197 output
198 NO
199 */
View Code

猜你喜欢

转载自www.cnblogs.com/gaojunonly1/p/10348777.html