混合图的欧拉回路判定方法:

1.首先判断基图是否连通,不连通的话表示不可能,否则进入下一步。

2.对于无向边,随便确定一个方向

3.确定好了之后,整张图就变成了有向图,计算每个节点的入度与出度

4.如果有一个节点的入度—出度是奇数,那么表示不可能,否则进入下一步

5.建立网络,新增一个原点s,和汇点t,然后建立网络

  1. for(i=; i<=M; i++)
  2. if(ff[i]==)//如果是有向边
  3. AddEdge(u[i],v[i],);
  4. for(i=; i<=N; i++)
  5. {
  6. if(Ru[i]>Chu[i])
  7. AddEdge(i,t,(Ru[i]-Chu[i])/);
  8. else
  9. AddEdge(s,i,(Chu[i]++-Ru[i])/);
  10. }

6.计算网络最大流。

7.如果从S引出的边有流量的都是满流,那么表示存在,否则不存在。

8.把网络流中与S,T不关联的边找到,这些边中如果有流量等于1的边,那么将这些边反向,最终得到了一张欧拉图。

AC代码(网络最大流用了Dinic连续最短增广路算法):

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<string>
  4. #include<cmath>
  5. #include<vector>
  6. #include<queue>
  7. #include<algorithm>
  8. using namespace std;
  9.  
  10. const int maxn=+;
  11. const int INF=0x7FFFFFFF;
  12.  
  13. struct Edge
  14. {
  15. int from,to,cap,flow;
  16. };
  17. vector<Edge>edges;
  18. vector<int>G[maxn];
  19. bool vis[maxn];
  20. int d[maxn];
  21. int cur[maxn];
  22. int Ru[maxn];
  23. int Chu[maxn];
  24. int u[maxn],v[maxn],ff[maxn];
  25. int father[maxn];
  26. int m,s,t,tot;
  27. int N,M;
  28.  
  29. //求出层次网络
  30. bool BFS()
  31. {
  32. memset(vis,,sizeof(vis));
  33. queue<int>Q;
  34. Q.push(s);
  35. d[s]=;
  36. vis[s]=;
  37. while(!Q.empty())
  38. {
  39. int x=Q.front();
  40. Q.pop();
  41. for(int i=; i<G[x].size(); i++)
  42. {
  43. Edge& e=edges[G[x][i]];
  44. if(!vis[e.to]&&e.cap>e.flow)
  45. {
  46. vis[e.to]=;
  47. d[e.to]=d[x]+;
  48. Q.push(e.to);
  49. }
  50. }
  51. }
  52. return vis[t];
  53. }
  54.  
  55. //加边
  56. void AddEdge(int from,int to,int cap)
  57. {
  58. Edge r;
  59. r.from=from;
  60. r.to=to;
  61. r.cap=cap;
  62. r.flow=;
  63. edges.push_back(r);
  64. Edge d;
  65. d.from=to;
  66. d.to=from;
  67. d.cap=;
  68. d.flow=;
  69. edges.push_back(d);
  70. m=edges.size();
  71. G[from].push_back(m-);
  72. G[to].push_back(m-);
  73. }
  74.  
  75. //每个阶段来一次DFS增广
  76. int DFS(int x,int a)
  77. {
  78. if(x==t||a==) return a;
  79. int flow=,f;
  80. for(int i=cur[x]; i<G[x].size(); i++)
  81. {
  82. Edge& e=edges[G[x][i]];
  83. if(d[x]+==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>)
  84. {
  85. e.flow+=f;
  86. edges[G[x][i]^].flow-=f;
  87. flow+=f;
  88. a-=f;
  89. if(a==) break;
  90. }
  91. }
  92. return flow;
  93. }
  94.  
  95. //多个阶段,多次建立层次网络。
  96. int Maxflow(int ss,int tt)
  97. {
  98. int flow=;
  99. while(BFS())
  100. {
  101. memset(cur,,sizeof(cur));
  102. flow+=DFS(ss,INF);
  103. }
  104. return flow;
  105. }
  106.  
  107. int Find(int x)
  108. {
  109. if(x!=father[x]) father[x]=Find(father[x]);
  110. return father[x];
  111. }
  112.  
  113. int main()
  114. {
  115. int T,flag,i;
  116. scanf("%d",&T);
  117. while(T--)
  118. {
  119. scanf("%d%d",&N,&M);
  120. edges.clear();
  121. for(i=; i<maxn; i++) G[i].clear();
  122. flag=;
  123. s=,t=N+;//设置超级原点和超级汇点
  124. memset(Ru,,sizeof(Ru));
  125. memset(Chu,,sizeof(Chu));
  126. for(i=;i<=N;i++) father[i]=i;
  127. tot=N;
  128. for(i=; i<=M; i++)
  129. {
  130. scanf("%d%d%d",&u[i],&v[i],&ff[i]);
  131. int fx=Find(u[i]);
  132. int fy=Find(v[i]);
  133. if(fx!=fy)
  134. {
  135. father[fx]=fy;
  136. tot--;
  137. }
  138. Ru[v[i]]++;
  139. Chu[u[i]]++;
  140. }
  141. if(tot!=) flag=;
  142. if(flag)
  143. {
  144. for(i=; i<=N; i++)
  145. if(abs(Ru[i]-Chu[i])%==)
  146. {
  147. flag=;
  148. break;
  149. }
  150. }
  151. if(flag)
  152. {
  153. for(i=; i<=M; i++)
  154. if(ff[i]==)//如果是有向边
  155. AddEdge(u[i],v[i],);
  156. for(i=; i<=N; i++)
  157. {
  158. if(Ru[i]>Chu[i])
  159. AddEdge(i,t,(Ru[i]-Chu[i])/);
  160. else
  161. AddEdge(s,i,(Chu[i]++-Ru[i])/);
  162. }
  163. Maxflow(s,t);
  164. for(i=; i<edges.size(); i++)
  165. if(edges[i].from==s&&edges[i].cap!=edges[i].flow)
  166. {
  167. flag=;
  168. break;
  169. }
  170. }
  171. if(flag) printf("possible\n");
  172. else printf("impossible\n");
  173. }
  174. return ;
  175. }

HDU 1956 POJ 1637 Sightseeing tour的更多相关文章

  1. POJ 1637 Sightseeing tour(最大流)

    POJ 1637 Sightseeing tour 题目链接 题意:给一些有向边一些无向边,问能否把无向边定向之后确定一个欧拉回路 思路:这题的模型很的巧妙,转一个http://blog.csdn.n ...

  2. POJ 1637 Sightseeing tour (混合图欧拉路判定)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6986   Accepted: 2901 ...

  3. POJ 1637 - Sightseeing tour - [最大流解决混合图欧拉回路]

    嗯,这是我上一篇文章说的那本宝典的第二题,我只想说,真TM是本宝典……做的我又痛苦又激动……(我感觉ACM的日常尽在这张表情中了) 题目链接:http://poj.org/problem?id=163 ...

  4. POJ 1637 Sightseeing tour

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9276   Accepted: 3924 ...

  5. POJ 1637 Sightseeing tour (混合图欧拉回路)

    Sightseeing tour   Description The city executive board in Lund wants to construct a sightseeing tou ...

  6. 网络流(最大流) POJ 1637 Sightseeing tour

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 8628   Accepted: 3636 ...

  7. POJ 1637 Sightseeing tour (SAP | Dinic 混合欧拉图的判断)

    Sightseeing tour Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 6448   Accepted: 2654 ...

  8. POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)

    http://poj.org/problem?id=1637 题意:给出n个点和m条边,这些边有些是单向边,有些是双向边,判断是否能构成欧拉回路. 思路: 构成有向图欧拉回路的要求是入度=出度,无向图 ...

  9. poj 1637 Sightseeing tour——最大流+欧拉回路

    题目:http://poj.org/problem?id=1637 先给无向边随便定向,如果一个点的入度大于出度,就从源点向它连 ( 入度 - 出度 / 2 ) 容量的边,意为需要流出去这么多:流出去 ...

随机推荐

  1. C语言之函数的声明

    函数的声明 1.函数只能定义在函数外,不能定义在函数内 2.函数不允许重名,C语言中函数没有重载 3.函数只要一经定义,就可以在任意函数中调用 注意:如果函数定义在它调用之后,那么必须在调用之前,先声 ...

  2. 高频交易算法研发心得--WAVT指标(Warensoft交易量趋势指标)算法及应用

    高频交易算法研发心得--WAVT指标(Warensoft交易量趋势指标)算法及应用 注:WAVT指标由Warensoft(王宇)原创. 前面聊了一系列的常见应用指标,包括短线.长线的指标,并且也无耐的 ...

  3. Swift之父Chris Lattner将从Apple离职,加入特斯拉

        1月10日,Swift编程语言之父 Chris Lattner 在 swift-evolution 邮件列表中宣布,他将于本月底离开 Apple,Ted Kremenek 将接替他成为 Swi ...

  4. linux一句话问答(网络无关篇+网络相关篇+程序开发篇+经典图书)

    一句话问答(网络无关篇+网络相关篇+程序开发篇+经典图书) --------------------------目录-网络无关篇-目录-------------------------- 0001 修 ...

  5. input中的name,value以及label中的for

    input具有很多属性,比较常用的有type,value,name,placeholder,multiple,checked等.对于其中的name.value.label相关以及标签外的文字,我一直是 ...

  6. js的eval函数解析后台返回的json数据时为什加上圆括号eval("("+data+")"),而HTML页面定义的数据不用

    一,情况如下,这是成功代码: $(function () { $.ajax({ url: "Demo.aspx", type: "post", data: { ...

  7. 使用node.js编写脚本将JSON数据转换为SQL语句

    安装依赖模块 当node.js脚本在运行的时候,需要很多支持模块,这些模块存储在node_modules文件夹中.该脚本在执行过程中需要使用到fs.string-format两个支持模块,作用分别是: ...

  8. 校门外的树 OpenJudge 1.6.06

    06:校门外的树 总时间限制:  1000ms 内存限制:  65536kB 描述 某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米.我们可以把马路看成一个数轴,马路的一端在数轴0 ...

  9. python爬虫框架scrapy初识(一)

    Scrapy介绍 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中.所谓网络爬虫,就是一个在网上到处或定向抓取数据的 ...

  10. CoreJavaE10V1P3.4 第3章 Java的基本编程结构-3.4 变量

    1.在Java中,每一个变量都必须有一个类型,在变量声明是,类型必须在变量名之前.示例如下: double salary; int vacationDays; long earthPopulation ...