POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)
http://poj.org/problem?id=1637
题意:
给出n个点和m条边,这些边有些是单向边,有些是双向边,判断是否能构成欧拉回路。
思路:
构成有向图欧拉回路的要求是入度=出度,无向图的要求是所有顶点的度数为偶数。
但不管是那个,顶点的度数若是奇数,那都是不能构成的。
这道题目是非常典型的混合图欧拉回路问题,对于双向边,我们先随便定个向,然后就这样先记录好每个顶点的入度和出度。
如果有顶点的度数为奇数,可以直接得出结论,是不能构成欧拉回路的。
那么,如果都是偶数呢?
因为还会存在入度不等于出度的情况,那么这个时候就要通过改变改变双向边的方向来改变度数。对于每个顶点,如果出度大于入度,那么就将该点与源点相连,容量为(out-in)/2,代表需要改变几条双向边的方向,同理,如果入度大于出度,那么就将该点与汇点相连,容量为(in-out)/2。
那么,顶点之间如何连接呢?
对于双向边,将该两个顶点相连,容量为1,代表这条边可以反向一次。
最后,走一遍最大流,如果满流,就说明能够构成欧拉回路。
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
using namespace std;
typedef long long LL;
typedef pair<int,int> pll;
const int INF=0x3f3f3f3f;
const int maxn=+; struct Edge
{
int from,to,cap,flow;
Edge(int u,int v,int w,int f):from(u),to(v),cap(w),flow(f){}
}; struct Dinic
{
int n,m,s,t;
vector<Edge> edges;
vector<int> G[maxn];
bool vis[maxn];
int cur[maxn];
int d[maxn]; void init(int n)
{
this->n=n;
for(int i=;i<n;++i) G[i].clear();
edges.clear();
} void AddEdge(int from,int to,int cap)
{
edges.push_back( Edge(from,to,cap,) );
edges.push_back( Edge(to,from,,) );
m=edges.size();
G[from].push_back(m-);
G[to].push_back(m-);
} bool BFS()
{
queue<int> Q;
memset(vis,,sizeof(vis));
vis[s]=true;
d[s]=;
Q.push(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]=true;
d[e.to]=d[x]+;
Q.push(e.to);
}
}
}
return vis[t];
} 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[e.to]==d[x]+ && (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 s,int t)
{
this->s=s; this->t=t;
int flow=;
while(BFS())
{
memset(cur,,sizeof(cur));
flow +=DFS(s,INF);
}
return flow;
}
}DC; int in[maxn],out[maxn];
int u[maxn],v[maxn],w[maxn];
int n,m; int main()
{
//freopen("D:\\input.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
memset(in,,sizeof(in));
memset(out,,sizeof(out));
int src=,dst=n+;
DC.init(dst+); for(int i=;i<=m;i++)
{
scanf("%d%d%d",&u[i],&v[i],&w[i]);
out[u[i]]++;
in[v[i]]++;
} bool flag=true;
int full_flow=;
for(int i=;i<=n;i++)
{
if(((in[i]+out[i])&)) {flag=false;break;}
if(in[i]>out[i]) {DC.AddEdge(i,dst,(in[i]-out[i])/);full_flow+=(in[i]-out[i])/;}
if(out[i]>in[i]) DC.AddEdge(src,i,(out[i]-in[i])/);
} if(flag)
{
for(int i=;i<=m;i++)
if(!w[i]) DC.AddEdge(u[i],v[i],);
} if(flag)
{
int flow=DC.Maxflow(src,dst);
if(flow==full_flow) puts("possible");
else puts("impossible");
}
else puts("impossible");
}
return ;
}
POJ 1637 Sightseeing tour(混合图欧拉回路+最大流)的更多相关文章
- poj 1637 Sightseeing tour 混合图欧拉回路 最大流 建图
题目链接 题意 给定一个混合图,里面既有有向边也有无向边.问该图中是否存在一条路径,经过每条边恰好一次. 思路 从欧拉回路说起 首先回顾有向图欧拉回路的充要条件:\(\forall v\in G, d ...
- POJ 1637 Sightseeing tour ★混合图欧拉回路
[题目大意]混合图欧拉回路(1 <= N <= 200, 1 <= M <= 1000) [建模方法] 把该图的无向边随便定向,计算每个点的入度和出度.如果有某个点出入度之差为 ...
- POJ 1637 Sightseeing tour (混合图欧拉回路)
Sightseeing tour Description The city executive board in Lund wants to construct a sightseeing tou ...
- POJ 1637 Sightseeing tour(混合图的欧拉回路)
题目链接 建个图,套个模板. #include <cstdio> #include <cstring> #include <iostream> #include & ...
- poj1637 Sightseeing tour(混合图欧拉回路)
题目链接 题意 给出一个混合图(有无向边,也有有向边),问能否通过确定无向边的方向,使得该图形成欧拉回路. 思路 这是一道混合图欧拉回路的模板题. 一张图要满足有欧拉回路,必须满足每个点的度数为偶数. ...
- POJ1637 Sightseeing tour (混合图欧拉回路)(网络流)
Sightseeing tour Time Limit: 1000MS Me ...
- POJ 1637 Sightseeing tour 建图+网络流
题意: 给定一个混合图,所谓混合图就是图中既有单向边也有双向边,现在求这样的图是否存在欧拉回路. 分析: 存在欧拉回路的有向图,必须满足[入度==出度],现在,有些边已经被定向,所以我们直接记录度数即 ...
- poj1637 Sightseeing tour 混合图欧拉回路判定
传送门 第一次做这种题, 尽管ac了但是完全不知道为什么这么做. 题目就是给一些边, 有向边与无向边混合, 问你是否存在欧拉回路. 做法是先对每个点求入度和出度, 如果一条边是无向边, 就随便指定一个 ...
- POJ 1637 Sightseeing tour(最大流)
POJ 1637 Sightseeing tour 题目链接 题意:给一些有向边一些无向边,问能否把无向边定向之后确定一个欧拉回路 思路:这题的模型很的巧妙,转一个http://blog.csdn.n ...
- POJ 1637 - Sightseeing tour - [最大流解决混合图欧拉回路]
嗯,这是我上一篇文章说的那本宝典的第二题,我只想说,真TM是本宝典……做的我又痛苦又激动……(我感觉ACM的日常尽在这张表情中了) 题目链接:http://poj.org/problem?id=163 ...
随机推荐
- CRUX下实现进程隐藏(3)
通过一个内核模块拦截文件系统的回调函数来实现进程隐藏. VFS(Virtual File System)是Linux在实际文件系统(如ext3,ext4,vfat等)上抽象出的一个文件系统模型,简单来 ...
- Android在ArrayAdapter<>里如何得到List<>的Items
public class ItemAdapter extends ArrayAdapter<DemoModel> { private final List<DemoModel> ...
- 170516、ActiveMQ 的安装与使用(单节点)
ActiveMQ 的安装与使用(单节点)IP: 192.168.4.101环 境: CentOS 6.6 . JDK71. 安装 JDK 并配置环境变量(略)JAVA_HOME=/usr/local/ ...
- web框架们~Django~Flask~Tornado
1.web框架本质 2.Django 3.Flask 4.Tornado
- avaScript 的基础学习(一)
JavaScript概述 JavaScript由三部分组成: JavaScript的基础 JS的引入方式: JS的数据类型: 运算符: 流程控制: JavaScript的对象 BOM对象 DOM Ev ...
- tomcat设置编码格式utf8
利用request.setCharacterEncoding("UTF-8");来设置Tomcat接收请求的编码格式,只对POST方式提交的数据有效,对GET方式提交的数据无效! ...
- Python性能鸡汤(转)
英文原文:http://blog.monitis.com/index.php/2012/02/13/python-performance-tips-part-1/ 英文原文:http://blog.m ...
- python修改镜像源
pip升级:python -m pip install --upgrade pip https://www.cnblogs.com/andy9468/p/10319442.html 1.在命令中临时修 ...
- Java API操作HA方式下的Hadoop
通过java api连接Hadoop集群时,如果集群支持HA方式,那么可以通过如下方式设置来自动切换到活动的master节点上.其中,ClusterName 是可以任意指定的,跟集群配置无关,dfs. ...
- WebDriver API 实例详解(三)
二十一.模拟鼠标右键事件 被测试网页的网址: http://www.sogou.com Java语言版本的API实例代码: package test; import org.testng.annota ...