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 ...
随机推荐
- C/C++程序编译流程
单个文件的编译过程 多个文件的编译过程
- 【BZOJ4524】[Cqoi2016]伪光滑数 堆(模拟搜索)
[BZOJ4524][Cqoi2016]伪光滑数 Description 若一个大于1的整数M的质因数分解有k项,其最大的质因子为Ak,并且满足Ak^K<=N,Ak<128,我们就称整数M ...
- iOS 如何在视图中添加一个用xib创建的view
NSArray *nib = [[NSBundle mainBundle]loadNibNamed:[pages objectAtIndex:] owner:self options:nil]; // ...
- VS2012编译FFmpeg 2.1.4
这次的目标是完整编译FFmpeg包括汇编代码,并且尽量少修改源代码. 环境是WIN7 64位,VS2012, Intel.Parallel.Studio.XE.2013.SP1 一. 安装MinGW, ...
- Css-常用css初始化
/*PC初始化*/ * {;;; } body, html { width: 100%; height: 100%; min-width: 1024px; } body { font-size: 14 ...
- DetaSet更新数据
用到的控件:DataGridView(展示数据), Button控件,更名[更新] using System; using System.Collections. ...
- 2014年web页面上的3D新产品介绍
地图对于数据的可视化展现有独到的显示方式,首先是底图.地图提供了一个定位的蓝图,让用例数据可以有参考的背景,因此底图通常是线画矢量图或者影像图.互联网上提供这种服务的基本以Google风格,也就是Ti ...
- SLF4J其实只是一个门面服务而已,他并不是真正的日志框架,真正的日志的输出相关的实现还是要依赖Log4j、logback等日志框架的。
小结: 1.加层: 每一种日志框架都有自己单独的API,要使用对应的框架就要使用其对应的API,这就大大的增加应用程序代码对于日志框架的耦合性. 为了解决这个问题,就是在日志框架和应用程序之间架设一个 ...
- Ubuntu18.04 英文系统下安装中文输入法
今天尝试了Ubuntu18.04LTS(依旧装的英文版)发现按照之前的方法( http://www.cnblogs.com/asmer-stone/p/5227188.html)安装中文输入法不行了, ...
- Spark2.0 shuffle service
Spark 的shuffle 服务是spark的核心,本文介绍了非ExternalShuffleClient的方式,看BlockService的整个架构.ShuffleClient是整个框架的基础,有 ...