【题目描述】:
有一天一位灵魂画师画了一张图,现在要你找出欧拉回路,即在图中找一个环使得每条边都在环上出现恰好一次。
一共两个子任务:
这张图是无向图。( 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 }
原文:https://www.cnblogs.com/66dzb/p/11188094.html