51nod 1967 路径定向(不错的欧拉回路)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1967

题意:

思路:

出度=入度,这很容易想到欧拉回路,事实上,这道题目也确实是用欧拉回路来做的,之前一直觉得应该用网络流来做,可惜想不出,后来看官方题解说也是可以的,但是复杂度太高。

对于每条边,先假设它为无向边,奇点的个数肯定是偶数个,对于这些奇点,我们可以两两连条边,使它们变成偶点,这样一来就肯定存在欧拉回路了,跑一遍就可以了。新加的边是不会影响结果的。

这道题目有点卡时间,用printf输出会超时,得用putchar。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,ll> pll;
15 const int inf = 0x3f3f3f3f;
16 const int maxn=1e6+5;
17 const int mod=1e9+7;
18
19 int n, m;
20 int vis[maxn];
21 int ans[maxn];
22 int flag[maxn];
23 int degree[maxn];
24
25 struct node
26 {
27     int u,v;
28 }e[maxn];
29
30 vector<int> G[maxn],p;
31
32 void dfs(int x)
33 {
34     vis[x]=1;
35     for(int i=0;i<G[x].size();i++)
36     {
37         int idx=G[x][i];
38         if(flag[idx])   continue;
39         if(e[idx].u==x)  {flag[idx]=1;dfs(e[idx].v);}
40         else {flag[idx]=2;dfs(e[idx].u);}
41     }
42 }
43
44 int main()
45 {
46     //freopen("in.txt","r",stdin);
47     scanf("%d%d",&n,&m);
48     for(int i=0;i<m;i++)
49     {
50         int u,v;
51         scanf("%d%d",&u,&v);
52         e[i].u=u, e[i].v=v;
53         G[u].push_back(i);
54         G[v].push_back(i);
55         degree[u]++;
56         degree[v]++;
57     }
58     for(int i=1;i<=n;i++)  if(degree[i]&1)  p.push_back(i);
59     for(int i=0;i<p.size();i+=2)
60     {
61         e[i/2+m].u=p[i], e[i/2+m].v=p[i+1];
62         G[p[i]].push_back(i/2+m);
63         G[p[i+1]].push_back(i/2+m);
64     }
65     for(int i=1;i<=n;i++)
66     {
67         if(!vis[i])  dfs(i);
68     }
69     printf("%d\n",n-p.size());
70     for(int i=0;i<m;i++)
71     {
72         if(flag[i]==1)  putchar(‘0‘);
73         else putchar(‘1‘);
74     }
75     printf("\n");
76     return 0;
77 }
时间: 2024-08-03 16:37:20

51nod 1967 路径定向(不错的欧拉回路)的相关文章

图的路径:欧拉路(欧拉回路)

欧拉路的相关概念: 1.能从无向图中的一个顶点出发,并走出一条道路,每条边恰好经过一次,这样的路线就叫做欧拉路: 2.找欧拉路首先要判断是否存在欧拉路: 一个无向图存在欧拉路当且仅当该图是连通的,且有且只有0或2个点的度数是奇数,为2时这两个点只能作为欧拉路径的起点和终点(0个时称为欧拉回路). 3.确定存在欧拉路之后,开始构造欧拉路: 欧拉路参考:http://blog.csdn.net/shahdza/article/details/6630108 等做完题,再来补充.

【题解】51nod1967 路径定向

第一次写欧拉回路,实际上只要dfs下去就可以了,反正每条边都是要遍历一遍的…… 关键有两个性质:1.一个无向图存在欧拉回路,当且仅当该图所有顶点度数都为偶数,且该图是连通图.2.一个有向图存在欧拉回路,所有顶点的入度等于出度且该图是连通图. 所以我们可以将所有的奇点之间两两连边使得它们成为偶点.此时这张图上必然存在欧拉路径,也就是所有顶点的入度等于出度,我们只需要减去奇点即可. #include <bits/stdc++.h> using namespace std; #define maxn

51nod 1443 路径和树——最短路生成树

题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 不只是做一遍最短路.还要在可以选的边里选最短的才行. 以为是求一遍最短路,然后按边权对边排序,哪条边两边的dis正好吻合,就把该边的边权加到ans里,把两端加到并查集里. 但其实不对.因为忽略了方向.比如如果有多个点同样地可以更新一个点,算的时候可能这多个点都因为那个点而被合到了并查集里,但其实只能有一个被合进去. 其实只要松弛点的时候如果dis[v]==d

51Nod 1443 路径和树

还是一道很简单的基础题,就是一个最短路径树的类型题目 我们首先可以发现这棵树必定满足从1出发到其它点的距离都是原图中的最短路 换句话说,这棵树上的每一条边都是原图从1出发到其它点的最短路上的边 那么直接跑最短路,SPFA,不存在的?我只信DJ,然后记录那些边在最短路上 然后直接跑MST即可.是不是很经典的水题 然后我又莫名拿了Rank1(没办法天生自带小常数) CODE #include<cstdio> #include<cctype> #include<cstring>

UVA 10735 Euler Circuit 混合图的欧拉回路(最大流,fluery算法)

题意:给一个图,图中有部分是向边,部分是无向边,要求判断是否存在欧拉回路,若存在,输出路径. 分析:欧拉回路的定义是,从某个点出发,每条边经过一次之后恰好回到出发点. 无向边同样只能走一次,只是不限制方向而已,那么这个情况下就不能拆边.不妨先按照所给的start和end的顺序,初步定下该无向边的顺序(若不当,一会再改).那么有个问题,我们需要先判断其是否存在欧拉回路先. 混合图不满足欧拉回路因素有:(1)一个点的度(无论有无向)是奇数的,那么其肯定不能满足出边数等于入边数.(2)有向边的出入度过

CodeForces 21D Traveling Graph 状压dp+欧拉回路

题目链接:点击打开链接 题意: 给定n个点m条边的无向图 求从1点开始经过每条边至少一次最后回到1点的最小路程 显然就是找一条路径可重复的欧拉回路 思路: 首先对于欧拉回路的结论是:所有点的度数都为偶数 因为所有边至少经过一次,那么可以把题意转换成加最少多少条边使得图满足以上结论 而加的边目的是为了把奇度数转成偶度数,先floyd一下得到任意点间加边的最小花费 dp[i]表示状态i下度数都为偶数的最小花费. 状压dp,把i状态下,所有未选择的点中挑2个奇度数的转移即可. #include <cs

bzoj 2095: [Poi2010]Bridges(二分法+混合图的欧拉回路)

[题意] 给定n点m边的无向图,对于边u,v,从u到v边权为c,从v到u的边权为d,问能够经过每条边一次且仅一次的最小权值和. [思路] 二分答案mid,然后切断权值大于mid的边,原图就变成了一个既有无向边又有有向边的混合图,则问题转化为求混合图上是否存在一个欧拉回路. 无向图存在欧拉回路,当且仅当图的所有顶点度数都为偶数且图连通.      有向图存在欧拉回路,当且仅当图的所有顶点入度等于初度且图连通. 一条边仅经过一次,所以无向边最终的归属就是有向边,即我们要给无向边定向使存在欧拉回路.

UVA 10735 混合图的欧拉回路

题意: 判断混合图中是否存在欧拉回路,如果存在欧拉回路,输出路径. 思路: 欧拉回路 存在每条边经过且只经过一次后回到原点的路径 在混合图中存在欧拉回路,需要满足以下条件: 1.把所有无向边任意规定一个方向后,对于每个点,满足 |入度-出度| % 2 == 0 2.按照上面已经规定的方向,利用 无向边 建图(有向边忽略掉),然后对于每个结点u,如果in[u]<out[u], 建边(s, u, |入度-出度| / 2);如果in[u]>out[u], 建边(u, t, |入度-出度| / 2)

Asp.NET 之 路径浅析

比如你的工程是Web(url是:http://localhost/web/default.aspx) Request.ApplicationPath 就是/Web 如果是站点就直接返回"/"; ------------------------------------------------------ (1)~/: 根目录,可以用在需要设置路径的控件比如:imagebutton,image等以及链接ascx文件,配置文件. (2)../: 相对当前目录的上层目录,好处是可以不知道文件夹