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

Description

The city executive board in Lund wants to construct a sightseeing tour by bus in Lund, so that tourists can see every corner of the beautiful city. They want to construct the tour so that every street in the city is visited exactly once. The bus should also start and end at the same junction. As in any city, the streets are either one-way or two-way, traffic rules that must be obeyed by the tour bus. Help the executive board and determine if it's possible to construct a sightseeing tour under these constraints.

Input

On the first line of the input is a single positive integer n, telling the number of test scenarios to follow. Each scenario begins with a line containing two positive integers m and s, 1 <= m <= 200,1 <= s <= 1000 being the number of junctions and streets, respectively. The following s lines contain the streets. Each street is described with three integers, xi, yi, and di, 1 <= xi,yi <= m, 0 <= di <= 1, where xi and yi are the junctions connected by a street. If di=1, then the street is a one-way street (going from xi to yi), otherwise it's a two-way street. You may assume that there exists a junction from where all other junctions can be reached.

Output

For each scenario, output one line containing the text "possible" or "impossible", whether or not it's possible to construct a sightseeing tour.

Sample Input

4
5 8
2 1 0
1 3 0
4 1 1
1 5 0
5 4 1
3 4 0
4 2 1
2 2 0
4 4
1 2 1
2 3 0
3 4 0
1 4 1
3 3
1 2 0
2 3 0
3 2 0
3 4
1 2 0
2 3 1
1 2 0
3 2 0

Sample Output

possible
impossible
impossible
possible

Source

题目链接:

http://poj.org/problem?id=1637

就是对有无向边和有向边的混合图,判断存不存在欧拉回路。

参考下面的解释:

【混合图】
混合图(既有有向边又有无向边的图)中欧拉环、欧拉路径的判定需要借助网络流!

(1)欧拉环的判定:
一开始当然是判断原图的基图是否连通,若不连通则一定不存在欧拉环或欧拉路径(不考虑度数为0的点)。

其实,难点在于图中的无向边,需要对所有的无向边定向(指定一个方向,使之变为有向边),使整个图变成一个有向欧拉图(或有向半欧拉图)。若存在一个定向满足此条件,则原图是欧拉图(或半欧拉图)否则不是。关键就是如何定向?

首先给原图中的每条无向边随便指定一个方向(称为初始定向),将原图改为有向图G',然后的任务就是改变G'中某些边的方向(当然是无向边转化来的,原混合图中的有向边不能动)使其满足每个点的入度等于出度。
设D[i]为G'中(点i的出度 - 点i的入度)。可以发现,在改变G'中边的方向的过程中,任何点的D值的奇偶性都不会发生改变(设将边<i, j>改为<j, i>,则i入度加1出度减1,j入度减1出度加1,两者之差加2或减2,奇偶性不变)!而最终要求的是每个点的入度等于出度,即每个点的D值都为0,是偶数,故可得:若初始定向得到的G'中任意一个点的D值是奇数,那么原图中一定不存在欧拉环!

若初始D值都是偶数,则将G'改装成网络:设立源点S和汇点T,对于每个D[i]>0的点i,连边<S, i>,容量为D[i]/2;对于每个D[j]<0的点j,连边<j, T>,容量为-D[j]/2;G'中的每条边在网络中仍保留,容量为1(表示该边最多只能被改变方向一次)。求这个网络的最大流,若S引出的所有边均满流,则原混合图是欧拉图,将网络中所有流量为1的中间边(就是不与S或T关联的边)在G'中改变方向,形成的新图G''一定是有向欧拉图;若S引出的边中有的没有满流,则原混合图不是欧拉图。

为什么能这样建图?
考虑网络中的一条增广路径S-->i-->...-->j-->T,将这条从i到j的路径在G'中全部反向,则:i的入度加1出度减1,j的入度减1出度加1,路径中其它点的入度出度均不变。而i是和S相连的,因此初始D[i]>0,即i的出度大于入度,故这样反向之后D[i]减少2;同理,j是和T相连的,这样反向之后D[j]增加2。因此,若最大流中边<S, i>满流(流量为初始D[i]/2),此时D[i]值就变成了0,也就是i的入度等于出度。因此只要使所有S引出的边全部满流,所有初始D值>0的点的D值将等于0,又因为将边变向后所有点的D值之和不变,所有初始D值小于0的点的D值也将等于0,而初始D值等于0的D点既不与S相连也不与T相连,所以它们是网络中的中间点,而中间点的流入量等于流出量,故它们的入度和出度一直不变,即D值一直为0。因此,整个图G'成为欧拉图。

(2)欧拉路径的判定:
首先可以想到的是枚举欧拉路径的起点i和终点j,然后在图中添加边<j, i>,再求图中是否有欧拉回路即可。但是,该算法的时间复杂度达到了O(M * 最大流的时间),需要优化。
前面已经说过,在将边变向的过程中任何点的D值的奇偶性都不会改变,而一个有向图有欧拉路径的充要条件是基图连通且有且只有一个点的入度比出度少1(作为欧拉路径的起点),有且只有一个点的入度比出度多1(作为终点),其余点的入度等于出度。这就说明,先把图中的无向边随便定向,然后求每个点的D值,若有且只有两个点的初始D值为奇数,其余的点初始D值都为偶数,则有可能存在欧拉路径(否则不可能存在)。进一步,检查这两个初始D值为奇数的点,设为点i和点j,若有D[i]>0且D[j]<0,则i作起点j作终点(否则若D[i]与D[j]同号则不存在欧拉路径),连边<j, i>,求是否存在欧拉环即可(将求出的欧拉环中删去边<j, i>即可)。这样只需求一次最大流。

就是转化成最大流,最一次最大流,看是不是满流

 /* ***********************************************
Author :kuangbin
Created Time :2014-2-3 11:26:49
File Name :E:\2014ACM\专题学习\图论\欧拉路\混合图\POJ1637.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; const int MAXN = ;
//最大流ISAP部分
const int MAXM = ;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to,next,cap,flow;
}edge[MAXM];
int tol;
int head[MAXN];
int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
void init()
{
tol = ;
memset(head,-,sizeof(head));
}
void addedge(int u,int v,int w,int rw = )
{
edge[tol].to = v;
edge[tol].cap = w;
edge[tol].next = head[u];
edge[tol].flow = ;
head[u] = tol++;
edge[tol].to = u;
edge[tol].cap = rw;
edge[tol].next = head[v];
edge[tol].flow = ;
head[v] = tol++;
}
int sap(int start,int end,int N)
{
memset(gap,,sizeof(gap));
memset(dep,,sizeof(dep));
memcpy(cur,head,sizeof(head));
int u = start;
pre[u] = -;
gap[] = N;
int ans = ;
while(dep[start] < N)
{
if(u == end)
{
int Min = INF;
for(int i = pre[u]; i != -;i = pre[edge[i^].to])
if(Min > edge[i].cap - edge[i].flow)
Min = edge[i].cap - edge[i].flow;
for(int i = pre[u];i != -;i = pre[edge[i^].to])
{
edge[i].flow += Min;
edge[i^].flow -= Min;
}
u = start;
ans += Min;
continue;
}
bool flag = false;
int v;
for(int i = cur[u];i != -;i = edge[i].next)
{
v = edge[i].to;
if(edge[i].cap - edge[i].flow && dep[v] + == dep[u])
{
flag = true;
cur[u] = pre[v] = i;
break;
}
}
if(flag)
{
u = v;
continue;
}
int Min = N;
for(int i = head[u];i != -;i = edge[i].next)
if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min)
{
Min = dep[edge[i].to];
cur[u] = i;
}
gap[dep[u]]--;
if(!gap[dep[u]])return ans;
dep[u] = Min+;
gap[dep[u]]++;
if(u != start)u = edge[pre[u]^].to;
}
return ans;
}
//the end of 最大流部分 int in[MAXN],out[MAXN];//每个点的出度和入度 int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int T;
int n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init();
int u,v,w;
memset(in,,sizeof(in));
memset(out,,sizeof(out));
while(m--)
{
scanf("%d%d%d",&u,&v,&w);
out[u]++; in[v]++;
if(w == )//双向
addedge(u,v,);
}
bool flag = true;
for(int i = ;i <= n;i++)
{
if(out[i] - in[i] > )
addedge(,i,(out[i] - in[i])/);
else if(in[i] - out[i] > )
addedge(i,n+,(in[i] - out[i])/);
if((out[i] - in[i]) & )
flag = false;
}
if(!flag)
{
printf("impossible\n");
continue;
}
sap(,n+,n+);
for(int i = head[]; i != -;i = edge[i].next)
if(edge[i].cap > && edge[i].cap > edge[i].flow)
{
flag = false;
break;
}
if(flag)printf("possible\n");
else printf("impossible\n");
}
return ;
}

POJ 1637 Sightseeing tour (混合图欧拉路判定)的更多相关文章

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

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

  2. POJ 1637 Sightseeing tour ★混合图欧拉回路

    [题目大意]混合图欧拉回路(1 <= N <= 200, 1 <= M <= 1000) [建模方法] 把该图的无向边随便定向,计算每个点的入度和出度.如果有某个点出入度之差为 ...

  3. poj 1637 Sightseeing tour 混合图欧拉回路 最大流 建图

    题目链接 题意 给定一个混合图,里面既有有向边也有无向边.问该图中是否存在一条路径,经过每条边恰好一次. 思路 从欧拉回路说起 首先回顾有向图欧拉回路的充要条件:\(\forall v\in G, d ...

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

    题目链接 建个图,套个模板. #include <cstdio> #include <cstring> #include <iostream> #include & ...

  5. POJ 1637 Sightseeing tour 建图+网络流

    题意: 给定一个混合图,所谓混合图就是图中既有单向边也有双向边,现在求这样的图是否存在欧拉回路. 分析: 存在欧拉回路的有向图,必须满足[入度==出度],现在,有些边已经被定向,所以我们直接记录度数即 ...

  6. POJ 1637 Sightseeing tour(最大流)

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

  7. [POJ 1637] Sightseeing tour(网络流)

    题意 (混合图的欧拉回路判定) 给你一个既存在有向边, 又存在无向边的图. 问是否存在欧拉回路. \(N ≤ 200, M ≤ 1000\) 题解 难点在于无向边. 考虑每个点的度数限制. 我们先对无 ...

  8. HDU 1956 POJ 1637 Sightseeing tour

    混合图的欧拉回路判定方法: 1.首先判断基图是否连通,不连通的话表示不可能,否则进入下一步. 2.对于无向边,随便确定一个方向 3.确定好了之后,整张图就变成了有向图,计算每个节点的入度与出度 4.如 ...

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

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

随机推荐

  1. 调用discuz编辑器再也不是问题了

    前面讲了如何开发一个discuz的特殊主题插件,详情可在此查看discuz特殊主题插件开发步骤和犯的愚蠢错误.上一篇文章讲解的是一些简单的开发步骤,不涉及到具体的编码.网页编辑器之类的都是系统默认带过 ...

  2. web缓存

    web缓存HTTP协议的一个核心特性,它能最小化网络流量,并且提升用户所感知的整个系统响应速度. 什么能被缓存? *Logo和商标图像 *普通的不变化的图像(例如,导航图标) *CSS样式表 *普通的 ...

  3. Oracle PL/SQL实战代码下载

    最近在学习PL/SQL编程,算是一个进阶吧,书没带光盘,所以按照书中的地址去下载样例,无法下载,到图灵官网找到了源代码下载地址,无法下载的留邮箱,我发给大家 下载地址: http://www.itur ...

  4. Windows上搭建hadoop开发环境

    前言 Windows下运行Hadoop,通常有两种方式:一种是用VM方式安装一个Linux操作系统,这样基本可以实现全Linux环境的Hadoop运行:另一种是通过Cygwin模拟Linux环境.后者 ...

  5. Spring4.1.0 整合quartz1.8.2 时 : class not found : org.springframework.scheduling.quartz.JobDetailBean

    最近做一个 Spring4.1.0 集成 quartz1.8.2 定时器功能,一直报 class not found : org.springframework.scheduling.quartz.J ...

  6. HBase之集群状态

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.*; import org.apache.had ...

  7. LayoutInflater和inflate()

    LayoutInflater LayoutInflater抽象类是用来加载XML布局文件(UI界面)的. 作用: 1.对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater. ...

  8. spring-mvc.xml中的配置

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...

  9. 在python中使用matplotlib中的Matplotlib-Animation “No MovieWriters Available”

    在使用官方的示例代码中,一部分使用了ffmpeg 在执行时会报如题一样的错误 解决: 下载windows的版本,解压,然后将bin目录加入系统环境变量的路径中 如:D:\Program Files\f ...

  10. css实现一段不够一行时居中显示,多于一行时两端对齐

    今天有遇到这个问题,不够一行要居中才好看,多于一行居中又很难看: 居中 两端对齐 一开始想用text-align-last:center; 可是这样结果是这样的: 单行的居中了 可是多行的最后一行也居 ...