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

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

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

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

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

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

for(i=; i<=M; i++)
if(ff[i]==)//如果是有向边
AddEdge(u[i],v[i],);
for(i=; i<=N; i++)
{
if(Ru[i]>Chu[i])
AddEdge(i,t,(Ru[i]-Chu[i])/);
else
AddEdge(s,i,(Chu[i]++-Ru[i])/);
}

6.计算网络最大流。

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

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

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

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std; const int maxn=+;
const int INF=0x7FFFFFFF; struct Edge
{
int from,to,cap,flow;
};
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
int Ru[maxn];
int Chu[maxn];
int u[maxn],v[maxn],ff[maxn];
int father[maxn];
int m,s,t,tot;
int N,M; //求出层次网络
bool BFS()
{
memset(vis,,sizeof(vis));
queue<int>Q;
Q.push(s);
d[s]=;
vis[s]=;
while(!Q.empty())
{
int x=Q.front();
Q.pop();
for(int i=; i<G[x].size(); i++)
{
Edge& e=edges[G[x][i]];
if(!vis[e.to]&&e.cap>e.flow)
{
vis[e.to]=;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
} //加边
void AddEdge(int from,int to,int cap)
{
Edge r;
r.from=from;
r.to=to;
r.cap=cap;
r.flow=;
edges.push_back(r);
Edge d;
d.from=to;
d.to=from;
d.cap=;
d.flow=;
edges.push_back(d);
m=edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} //每个阶段来一次DFS增广
int DFS(int x,int a)
{
if(x==t||a==) return a;
int flow=,f;
for(int i=cur[x]; i<G[x].size(); i++)
{
Edge& e=edges[G[x][i]];
if(d[x]+==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>)
{
e.flow+=f;
edges[G[x][i]^].flow-=f;
flow+=f;
a-=f;
if(a==) break;
}
}
return flow;
} //多个阶段,多次建立层次网络。
int Maxflow(int ss,int tt)
{
int flow=;
while(BFS())
{
memset(cur,,sizeof(cur));
flow+=DFS(ss,INF);
}
return flow;
} int Find(int x)
{
if(x!=father[x]) father[x]=Find(father[x]);
return father[x];
} int main()
{
int T,flag,i;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&M);
edges.clear();
for(i=; i<maxn; i++) G[i].clear();
flag=;
s=,t=N+;//设置超级原点和超级汇点
memset(Ru,,sizeof(Ru));
memset(Chu,,sizeof(Chu));
for(i=;i<=N;i++) father[i]=i;
tot=N;
for(i=; i<=M; i++)
{
scanf("%d%d%d",&u[i],&v[i],&ff[i]);
int fx=Find(u[i]);
int fy=Find(v[i]);
if(fx!=fy)
{
father[fx]=fy;
tot--;
}
Ru[v[i]]++;
Chu[u[i]]++;
}
if(tot!=) flag=;
if(flag)
{
for(i=; i<=N; i++)
if(abs(Ru[i]-Chu[i])%==)
{
flag=;
break;
}
}
if(flag)
{
for(i=; i<=M; i++)
if(ff[i]==)//如果是有向边
AddEdge(u[i],v[i],);
for(i=; i<=N; i++)
{
if(Ru[i]>Chu[i])
AddEdge(i,t,(Ru[i]-Chu[i])/);
else
AddEdge(s,i,(Chu[i]++-Ru[i])/);
}
Maxflow(s,t);
for(i=; i<edges.size(); i++)
if(edges[i].from==s&&edges[i].cap!=edges[i].flow)
{
flag=;
break;
}
}
if(flag) printf("possible\n");
else printf("impossible\n");
}
return ;
}

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. CoreCRM 开发实录 —— 单元测试之 Mock UserManager 和 SignInManager

    单元测试的核心就是:只测试眼前的逻辑.这就要求所有的依赖项都要使用仿类来代替,也就是所谓的 Mock Object.在测试 ProfileRepository 和 AccountController ...

  2. [ios2]iphone编程中使用封装的NSLog来打印调试信息 【转】

    使用NSLog的一个风险是:它的运行会占用时间和设备资源. 简单而粗暴的解决方案是:在release前,将所有的NSLog注释掉.简单有效,但副作用是:下次你要调试时,又得将NSLog一个个取消注释. ...

  3. 手机端H5 header定义样式

    <meta content="width=device-width,initial-scale=1.0, maximum-scale=1.0, user-scalable=0" ...

  4. 将前台input中的数据异步传到后台并存入数据库

    将前台input中的数据异步传到后台并存入数据库 先看图: 利用ajax异步交互数据,并不是以json数组的形式将数据传到后台,而是利用字符数组的形式将其传到后台.动态新增每一行数据,将每一列对应的数 ...

  5. redhat7.3配置163 yum源

    redhat 的更新包只对注册的用户生效,所以我们需要自己手动更改成CentOS 的更新包,CentOS几乎和redhat是一样的,所以无需担心软件包是否可安装,安装之后是否有问题. 1.首先删除re ...

  6. 基于DDD的.NET项目搭建

    第一次写博客有点小激动,废话不多说先上图: 01_Client:存放UI相关的项目,比如ASP.NET MVC或者相关的Web Model及View Model项目. 02_Hosting:存放与Se ...

  7. nio简介

    上一篇  Java I/O演进与Linux网络I/O模型 一.传统BIO java传统bio编程概念: http://www.cnblogs.com/carl10086/p/6034563.html# ...

  8. ORACLE 使用sqluldr2和sqlldr进行导入导出

    oracle数据导出工具sqluldr2可以将数据以csv.txt等格式导出,适用于大批量数据的导出,导出速度非常快.导出后可以使用oracle loader工具将数据导入. 简介: Sqluldr2 ...

  9. mmmmmmmm

    // // AView.m // AutoLayout // // Created by ZhuYi on 16/5/24. // Copyright © 2016年 ZY. All rights r ...

  10. node + express 资料

    https://www.youtube.com/watch?v=65a5QQ3ZR2g&list=PL55RiY5tL51oGJorjEgl6NVeDbx_fO5jR https://www. ...